问题描述:
如果采用以下简单的的代码得到答案,则忽略了时间限制要求,面试必挂。(时间复杂度O(n))
class Solution {
public int search(int[] nums, int target) {
if(nums.length==1&&target==nums[0]){
return 0;
}else{ for(int i =0;i<nums.length;++i){
if(target==nums[i]){
return i;
}
}
}
return -1;
}
}
二分法解法:(时间复杂度O(logn))
class Solution {
public int search(int[] nums, int target) {
int lo = 0, hi = nums.length - 1, mid = 0;
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
if (nums[mid] == target) {
return mid;
}
// 先根据 nums[mid] 与 nums[lo] 的关系判断 mid 是在左段还是右段
if (nums[mid] >= nums[lo]) {
// 再判断 target 是在 mid 的左边还是右边,从而调整左右边界 lo 和 hi
if (target >= nums[lo] && target < nums[mid]) {
hi = mid - 1;
} else {
lo = mid + 1;
}
} else {
if (target > nums[mid] && target <= nums[hi]) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
}
return -1;
}
}
反思总结:
这一步之前少了等于号,导致结果错误,提示[1,3]数组时候输出错误。想一想,什么时候nums[mid]=nums[lo] ?只有当数组长度较小,根据前面 mid=lo+(hi-lo)/2 数组长度为 1 2 时候 等号成立。