【leetcode】剑指Offer面试题11 . 12
面试题11. 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
输入:[3,4,5,1,2]
输出:1
输入:[2,2,2,0,1]
输出:0
思路:
这个问题用暴力算法的话,简单来说是寻找数组最小值问题,(题目给定输入是递增排序的数组的一个旋转,也就是说,一般情况下第一个元素(最小的元素)旋转到了数组后面的某个位置)有很多种方法可以用,笔者在这里用了相邻元素的比较。
class Solution {
public int minArray(int[] numbers) {
if(numbers.length == 0) return 0;
if(numbers.length == 1) return numbers[0];
int i = 0;
for(; i < numbers.length - 1; i++){
//每个元素都与前一个元素比较,若比前面元素小,则跳出循环返回
if(numbers[i + 1] < numbers[i]){
break;
}
//说明是递增序列,返回numbers[0]
if(i == numbers.length - 2 && numbers[i + 1] >= numbers[i])return numbers[0];
}
return numbers[i + 1];
}
}
还可以使用二分法:排序数组的查找问题可以首先考虑使用二分法解决,通常可以将需要遍历的算法时间复杂度由O( N )降为O(log N),有时候会有更优解出现
class Solution {
public int minArray(int[] numbers) {
int i = 0, j = numbers.length - 1;
while (i < j) {
int m = (i + j) / 2;
if (numbers[m] > numbers[j]) i = m + 1;
else if (numbers[m] < numbers[j]) j = m;
else j--;
}
return numbers[i];
}
}
面试题12. 矩阵中的路径
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。
例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false
限制:
1 <= board.length <= 200
1 <= board[i].length <= 200
思路:深度优先搜索(DFS)
class Solution {
public boolean exist(char[][] board, String word) {
char[] words = word.toCharArray();
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; j++) {
if(dfs(board, words, i, j, 0)) return true;
}
}
return false;
}
boolean dfs(char[][] board, char[] words, int i, int j, int k) {
//越界或者不匹配,返回false
if(i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != words[k]) return false;
if(k == words.length - 1) return true;
char tmp = board[i][j];
//访问过的做标记
board[i][j] = '/';
boolean res = dfs(board, words, i + 1, j, k + 1) || dfs(board, words, i - 1, j, k + 1) ||
dfs(board, words, i, j + 1, k + 1) || dfs(board, words, i , j - 1, k + 1);
//标记还原
board[i][j] = tmp;
return res;
}
}