荷兰国旗问题
三色排序问题
对只包含0,1,2的整数数组进行排序,要求使用交换、原地排序,而不是利用计数进行排序,做到0全在数组左边,1在中间,2在右边
测试用例:
arr = [1,1,0,0,2,1,1,0]
输出:[0,0,0,1,1,1,1,2]
解题思路:
在数组左侧设置一个0区域,初始长度为0,在数组右侧设置一个2区域,初始长度为0
从左右到遍历,如果当前值为1,直接跳到下一个位置。
若当前数为0,则将其与0区域的下一个元素交换,并将0区域向右扩散。
若当前数为2,则将其与2区域的前一个元素交换,并将2区域向前扩散。判断交换后的当前值是否还需再次交换
直至当前位置与2区域的左边界相等为止
时间复杂度为O(n),空间复杂度为O(1)
def sort(arr):
if not arr:
return arr
index0 = 0
index2 = len(arr)-1
i = 0
while i <= index2:
if arr[i] == 0:
exchange(arr,i,index0)
index0 += 1
if arr[i] == 2:
exchange(arr,i,index2)
index2 -= 1
i -= 1 #这步很关键,与后面元素交换后,当前位置不变
i += 1
return arr
def exchange(arr,i,j):
arr[i],arr[j] = arr[j],arr[i]
有序矩阵查找练习题
在行列都排好序的矩阵中找数
0 1 2 5
2 3 4 7
4 4 4 8
5 7 7 9
若k为7,返回true;若k为6,返回false。
若矩阵为(m*n),该题最优解可以做到时间复杂度O(m+n),额外空间复杂度O(1)。
方法,从右上角或者左下角找。
解题思路:
从右上角开始查找,如果这个值大于被查找的值的话,减去一列
如果这个值比被查找的值小的话,减去一行
def search(arr,k):
if not arr:
return False
rows = len(arr)
cols = len(arr[0])
row = 0
col = cols -1
while rowand col>0:
if arr[row][col] > k:
col -= 1
elif arr[row][col] < k:
row += 1
else:
return True
return False
最短子数组问题
给定一个数组,要求返回该数组中需要排序的最短子数组的长度
测试用例:
arr=[1,5,4,3,2,6,7]
返回:4
因为只有[5,4,3,2]需要排序
解题思路:
从左到右遍历,记录最大值,只关心右边数比左边数小的这种情况,并记录发生这种情况最右的位置。
从右往左遍历,记录最小值,和比最小值大的最左边的数的下标。
最左位置至最右位置这段,就是需要排序的数组长度
def shortest_arr(arr):
if not arr:
return 0
n = len(arr)
max = arr[0]
min = arr[n-1]
left = n-1
right = 0
for i in range(1,len(arr)):
if arr[i] >= max:
max = arr[i]
else:
right = i
for i in range(n-1,-1,-1):
if arr[i] <= min:
min = arr[i]
else:
left = i
if leftreturn right-left+1
else:
return 0
给定一个整形数组arr,返回如果排序之后,相邻两数的最大差值。
例如:
1 2 3 4 7 8 9
最大是3,4 和7之间
不用考虑同一个桶的相邻数,只用考虑桶之间的相邻数。