在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
if not array:
return False
r1 = 0; r2 = len(array) - 1
c1 = 0; c2 = len(array[0]) - 1
while r1 <= r2 and c2 >= c1 :
if target == array[r1][c2]:
return True
elif target > array[r1][c2]:
r1 = r1 + 1
else :
c2 = c2 -1
return False
带输入版本:
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
if not array:
return 'false'
r1 = 0; r2 = len(array) - 1
c1 = 0; c2 = len(array[0]) - 1
while r1 <= r2 and c2 >= c1 :
if target == array[r1][c2]:
return 'true'
elif target > array[r1][c2]:
r1 = r1 + 1
else :
c2 = c2 -1
return 'false'
while True:
try:
S=Solution()
#字符串转为list
L=list(eval(raw_input()))
array=L[1]
target=L[0]
print(S.Find(target,array))
except:
break
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
二分查找:
注意如果数组元素允许重复,会出现一个特殊的情况:nums[l] == nums[m] == nums[h],此时无法确定解在哪个区间,需要切换到顺序查找。例如对于数组 {1,1,1,0,1},l、m 和 h 指向的数都为 1,此时无法知道最小数字 0 在哪个区间。
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if len(rotateArray) == 0:
return 0
l = 0; h = len(rotateArray) - 1
while l < h :
m = l + (h - l)/2
if rotateArray[m] == rotateArray[l] and rotateArray[m] == rotateArray[h]:
return self.minNumber(rotateArray, l, h)
if rotateArray[m] <= rotateArray[h]:
h = m
else:
l = m + 1
return rotateArray[l]
def minNumber(self,rotateArray, l, h):
for i in range(l,h):
if (rotateArray[i] > rotateArray[i + 1]):
return rotateArray[i + 1]
return rotateArray[l]
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
法一:lambda表达式
# 运行时间:24ms
# 占用内存:5852k
class Solution:
def reOrderArray(self, array):
# write code here
return sorted(array, key=lambda c : c % 2, reverse = True)
法二:操作数组
class Solution:
def reOrderArray(self, array):
# write code here
l = 0
r = len(array) - 1
while l <= r:
if (array[l] % 2) == 0 :
array.append(array[l])
array.pop(l)
r -= 1
else:
l += 1
return array
法三:冒牌排序
class Solution:
def reOrderArray(self, array):
# write code here
n = len(array)
for i in range(n):
for j in range(0, n-i-1):
if self.isEven(array[j]) and not self.isEven(array[j + 1]):
self.swap(array, j, j+1)
return array
def swap(self,array, l, h):
val = array[l]
array[l] = array[h]
array[h] = val
def isEven(self,x):
if x % 2 == 0 :
return True
else:
return False
法四:创建两个数组,一个保存奇数+一个保存偶数
class Solution:
def reOrderArray(self, array):
# write code here
list1 = []
list2 = []
i = 0
while i < len(array):
if (array[i] % 2 == 0):
list2.append(array[i])
else:
list1.append(array[i])
i += 1
return list1 + list2
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
if matrix == []:
return False
r1 = 0;r2 = len(matrix) - 1
c1 = 0;c2 = len(matrix[0]) - 1
result = []
while r1 <= r2 and c1 <= c2:
for i in range(c1, c2 + 1):
result.append(matrix[r1][i])
for i in range(r1 + 1, r2 + 1):
result.append(matrix[i][c2])
if r1 != r2:
for i in range(c2 - 1, c1 - 1, -1):
result.append(matrix[r2][i])
if c1 != c2:
for i in range(r2 - 1, r1, -1):
result.append(matrix[i][c1])
r1 += 1; r2 -= 1; c1 += 1; c2 -= 1
return result
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
法一:排序后找中位数
法二:统计次数后,消减
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if len(numbers) == 0:
return 0
count = 1
val = numbers[0]
for i in range(1,len(numbers)):
count = (count - 1 if numbers[i] != val else count + 1) # 统计出现次数
if count == 0:
val = numbers[i]
count = 1
count = 0
for i in numbers:
if i == val:
count += 1
return (val if count > len(numbers)//2 else 0) # 判断是否超过一半
给一个数组,返回它的最大连续子序列的和(子向量的长度至少是1)
例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。
动态规划
# -*- coding:utf-8 -*-
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
if len(array) == 0:
return 0
maxV = array[0]
tmp = array[0]
for i in range(1,len(array)):
if (array[i] + tmp) > array[i]:
tmp = array[i] + tmp
else:
tmp = array[i]
if tmp > maxV:
maxV = tmp
return maxV
利用python自带的max函数,可以更简便:
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
if len(array) == 0:
return 0
maxV = array[0]
tmp = array[0]
for i in range(1,len(array)):
tmp = max(array[i] + tmp, array[i])
maxV = max(tmp,maxV)
return maxV
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
# 很厉害的代码
class Solution:
def PrintMinNumber(self, numbers):
# write code here
if not numbers:
return ""
lmb = lambda n1, n2:int(str(n1)+str(n2))-int(str(n2)+str(n1))
array = sorted(numbers, cmp=lmb)
return ''.join([str(i) for i in array])
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
法1:归并排序,时间复杂度O(nlogn)
我的写法:相当于手写了一个归并排序!
count = 0
class Solution:
def InversePairs(self, data):
# write code here
global count
if data == []:
return 0
self.mergersort(data)
return count % 1000000007
def mergersort(self,data):
n = len(data)
if n < 2:
return
m = n // 2
s1 = data[:m]
s2 = data[m:]
self.mergersort(s1)
self.mergersort(s2)
self.merger(s1, s2, data)
def merger(self,s1,s2,s):
i = j = 0
global count
while i < len(s1) or j < len(s2):
if i > len(s1) - 1:
s[i+j] = s2[j]; j += 1
elif j > len(s2) - 1:
s[i+j] = s1[i]; i += 1
elif s1[i] < s2[j]:
s[i+j] = s1[i]; i += 1
else:
s[i+j] = s2[j]; j += 1
count += len(s1) - i
return s
别人的写法:
count = 0
class Solution:
def InversePairs(self, data):
global count
def MergeSort(lists):
global count
if len(lists) <= 1:
return lists
num = int( len(lists)/2 )
left = MergeSort(lists[:num])
right = MergeSort(lists[num:])
r, l=0, 0
result=[]
while l<len(left) and r<len(right):
if left[l] < right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1
count += len(left)-l
result += right[r:]
result += left[l:]
return result
MergeSort(data)
return count%1000000007
法二:暴力法
直接暴力法,双指针,判断当前指针的数是否大于第二个指针的数字。
# 运行超时不通过
class Solution:
def InversePairs(self, data):
# write code here
length = len(data)
count = 0
for i in range(length-1):
for j in range(i+1, length):
if data[i] > data[j]:
count += 1
return count%1000000007
法三:
将原数组排序,然后从小到大遍历排序数组,求这个数在原数组中的index,这个index就代表有多少个数字在该数的前面。
# 运行超时不通过
class Solution:
def InversePairs(self, data):
# write code here
data2 = sorted(data) # 相当于自动归并排序
length = len(data)
count = 0
for num in data2:
count += data.index(num)
data.remove(num)
return count%1000000007
统计一个数字在排序数组中出现的次数。
Input:
nums = 1, 2, 3, 3, 3, 3, 4, 6
K = 3
Output:
4
最简单的解法:
class Solution:
def GetNumberOfK(self, data, k):
# write code here
return data.count(k)
法二:顺序判断(适合数据量不大)
class Solution:
def GetNumberOfK(self, data, k):
# write code here
count = len(data)
i = 0
for j in range(count):
if data[j] == k:
i += 1
return i
法三:
从两头分别找第一个和最后一个k的位置,计算位置差
class Solution:
def GetNumberOfK(self, data, k):
# write code here
if len(data) == 0:
return 0
i = 0;
j = len(data) - 1
while i < j and data[i] != data[j]:
if data[i] < k:
i += 1
if data[j] > k:
j -= 1
if data[i] != k:
return 0
return j - i + 1
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路:
1.异或全部数组,得diff
2.找到diff最右侧第一个为1的位置,记为n位 ,diff &= -diff
3.利用n位为1或为0将原数组分为两组
4.对每组进行异或,可得到每组只出现一次的数字
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
# write code here
res = [0,0]
diff = 0
for i in array:
diff ^= i
diff &= -diff
for i in array:
if (i & diff) == 0:
res[0] ^= i
else:
res[1] ^= i
return res
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
# write code here
if numbers is None:
return False
for i in range(len(numbers)):
while numbers[i] != i:
if numbers[i] == numbers[numbers[i]]:
duplication[0] = numbers[i]
return True
self.swap(numbers, i, numbers[i])
return False
def swap(self, nums, i, j):
item = nums[i]
nums[i] = nums[j]
nums[j] = item
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)
解法:
分两段乘,先从左往右乘,在从右往左乘
class Solution:
def multiply(self, A):
# write code here
if A is None:
return None
B = [1] * len(A)
mul = 1
for i in range(len(A)):
B[i] = mul
mul *= A[i]
mul = 1
for i in range(len(A)- 1,-1,-1):
B[i] *= mul
mul *= A[i]
return B