旋转数组中的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
示例1:
输入:[3,4,5,1,2]
输出:1
示例2:
输入:[2,2,2,0,1]
输出:0
代码:
def minArray(self, numbers: List[int]) -> int:
i, j = 0, len(numbers)-1
while i < j:
m = (i+j)//2
if numbers[m] > numbers[j]:
i = m + 1
elif numbers[m] < numbers[j]:
j = m
else:
j -= 1
return numbers[j]
本题的关键使用二分查找,时间复杂度O(logn),空间复杂度O(1)
矩阵中的路径
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
示例1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例2:
输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false
代码:
def exist(self, board: List[List[str]], word: str) -> bool:
def DFS(i, j, k):
if not 0<=i<len(board) or not 0<=j<len(board[0]) or board[i][j] != word[k]:
return False
if k == len(word)-1: return True
tmp = board[i][j]
board[i][j] = '*'
res = DFS(i-1, j, k+1) or DFS(i+1, j, k+1) or DFS(i, j-1, k+1) or DFS(i, j+1, k+1)
board[i][j] = tmp
return res
for i in range(len(board)):
for j in range(len(board[0])):
if DFS(i, j, 0): return True
return False
矩阵搜索问题,可以考虑递归实现深度优先搜索DFS。
时间复杂度O(3KMN):最差情况下,需要遍历矩阵中长度为 K字符串的所有方案,时间复杂度为 O(3K) (上下左右除去回头还有3种可能);矩阵中共有 MxN 个起点,时间复杂度为 O(MN) 。
空间复杂度 O(K) : 搜索过程中的递归深度不超过 K ,因此系统因函数调用累计使用的栈空间占用 O(K)(因为函数返回后,系统调用的栈空间会释放)。