旋转数组的最小数字
题外话:
刚开始我看到题目的时候,脑子一直在想,直接遍历数组,这样最小的不就能找到最小的麽,不过去网上搜索了一下后,发现这确实是一个解决的办法,但时间复杂度为O(n),这样的答案达不到面试官的要求,所以大家做这种面试题的时候,要转换思路,在解决问题的同时,尽量给出最优解
好了,分析题目,可以知道得出结论:最小元素的左边序列递增,右边序列递减
初始化:首先起始元素就是旋转数组的第一个元素,末尾元素就是旋转数组的最后一个元素,中间元素的下标=(末尾下标-起始下标)/2+1
-
中间元素<起始元素小:
说明最小元素在[起始元素~中间元素],为什么?因为如果最小元素不在[起始元素 ~中间元素],说明这一段是第一个子序列的子序列,严格递增,是不可能出现中间元素<起始元素的情况 -
中间元素>起始元素:
说明最小元素在[中间元素~末尾元素],为什么?因为如果最小元素不在[中间元素 ~末尾元素],说明这一段是第二个子序列的子序列,严格递减,是不可能出现中间元素>末尾元素的情况 -
中间元素==起始元素:
最小元素一定在[中间元素~末尾元素],为什么?看结论
直到当前要判断的序列只有一个元素,即为最小元素
这样做的时间复杂度为O(log2n)
class Solution {
public int mainArray(int[] numbers)
{
int start=0,end=numbers.length-1,mid=0;
while(start<end)
{
mid=start+(end-start)/2+1;
if(numbers[start]>numbers[mid]) //最小元素在mid的左边序列
{
end=mid-1;
}
else //最小元素在mid的右边序列
{
start=mid+1;
}
}
return numbers[start];
}
public static void main(String[] args)
{
Solution ss=new Solution();
int[] numbers={3,4,5,1,2};
System.out.print(ss.mainArray(numbers));
}
}
矩阵中的路径
采用递归的方式进行上下左右的探索,这种办法时间复杂度和空间复杂度极高,但想不出其他办法
public class Solution {
public boolean hasPath(char[] matrix, int rows, int cols, char[] str)
{
int[] flag = new int[matrix.length];
for(int i = 0; i < rows; i ++){
for(int j = 0; j < cols; j ++){
if(helper(matrix, rows, cols, i, j, str, 0, flag)){
return true;
}
}
}
return false;
}
public static boolean helper(char[] matrix, int rows, int cols, int i, int j, char[] str, int k, int[] flag){
int index = i * cols + j;
if(i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index] == 1){
//下标不符合,index对应的值不为和字符数组中的不一致,或者该index已经被访问,这些情况只要有符合的就返回false
//只有上面的所有情况都不符合,也就是值相等,且没有访问过,下标不符合
return false;
}
if(k == str.length - 1){
return true;
}
flag[index] = 1;
if(helper(matrix, rows, cols, i - 1, j, str, k + 1, flag)
||helper(matrix, rows, cols, i + 1, j, str, k + 1, flag)
||helper(matrix, rows, cols, i, j - 1, str, k + 1, flag)
||helper(matrix, rows, cols, i , j + 1, str, k + 1, flag)){
return true;
}
flag[index] = 0;
return false;
}
}