这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
剑指 Offer 11. 旋转数组的最小数字
题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [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
方法一
朴素方法:遍历一遍数组记录最小值
class Solution {
public int minArray(int[] numbers) {
int res = 0x3f3f3f3f;
for (int x : numbers)
res = Math.min(x, res);
return res;
}
}
时间复杂度: O(n)
空间复杂度: O(1)
方法二
二分:此题得稍微做些调整才能用二分,根据二分的定义,在我们答案的左右两边应该分别满足不同的特性,即在本题中,答案左边的点都要大于等于数组的第一个元素,答案右边的都要小于数组的第一个元素,注意,答案右边的点不能小于等于。 所以,我们首先得把数组最后的元素中和第一个元素相等的元素删除。
class Solution {
public int minArray(int[] numbers) {
int n = numbers.length - 1;
if (n == 0) return numbers[0];
while(n != 0 && numbers[n] == numbers[0]) n --;
int l = 0, r = n;
while(l < r) {
int mid = l + r >> 1;
if (numbers[mid] < numbers[0]) r = mid;
else l = mid + 1;
}
return numbers[l] > numbers[0] ? numbers[0] : numbers[l];
}
}
时间复杂度: O(logn)
空间复杂度: O(1)
剑指 Offer 12. 矩阵中的路径
题目
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例 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
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
board 和 word 仅由大小写英文字母组成
方法一
深度优先搜索(回溯):枚举矩阵中的点,从该点开始往下搜:当该点的值和单词中的第index
位置的字符一样时,接着往下搜索;否则返回。直到搜到index
等于单词长度时,说明矩阵中存在该单词,返回true
class Solution {
int[] dx= {0,0,1,-1}, dy = {1,-1,0,0};
public boolean exist(char[][] board, String word) {
char[] s = word.toCharArray();
for (int i = 0; i < board.length; i ++ )
for (int j = 0; j < board[0].length; j ++ )
if (dfs(board, s, i, j, 0))
return true;
return false;
}
boolean dfs(char[][] board, char[] word, int x, int y, int index) {
if (board[x][y] != word[index]) return false;
if (index == word.length - 1) return true;
board[x][y] = '.';
for (int i = 0; i < 4; i ++ ) {
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a >= board.length || b < 0 || b >= board[0].length) continue;
if (board[a][b] != '.') {
if (dfs(board, word, a, b, index + 1))
return true;
}
}
board[x][y] = word[index];
return false;
}
}
时间复杂度: O(nm3^k),最差情况下,需要遍历矩阵中长度为 K 字符串的所有方案,时间复杂度为 O(3^k),有nm个点
空间复杂度: O(K),递归深度最深为字符串长度
注意: 当矩阵中的当前字符和单词的第index
个字符相等时,我们把矩阵中的当前字符改为.
,防止进入到下一层时,又回到该点。等到该层全部结束时,恢复现场。