Leetcode33
1.问题描述
2.解决方案
解法一:暴力法o(n)
class Solution {
public int search(int[] nums, int target) {
int i;
for (i = 0; i < nums.length ; i++) {
if(nums[i]==target) return i;
}
return -1;
}
}
解法二:二分查找变形o(logn)
思路就是把情况都列举出来,然后给出下一步二分的节点,但逻辑不难,就和普通二分一样,只不过普通二分很容易判断下一处left和right
1.如果等于mid,return
2.如果大于mid且左边有序–
3.如果大于mid且右边有序–
4.如果小于mid且左边有序–
5.如果小于mid且又边有序–
并且把mid可能在的情况都想到就行
然后也得到启发就是不只是有序的数组查找可以实现o(logn),部分有序有规律也可以使用二分,只不过分析出下一步的left和right要难一点!!!
还有5个注意点就是,大部分一定是<= ,这个要具体分析情况,要具体分析target到底在哪!!
class Solution {
public int search(int[] nums, int target) {
//检查
if(nums.length==0) return -1;
if(nums.length==1) return nums[0]==target?0:-1;
//二分查找
int left=0,right=nums.length-1;
//注意点1:left<=right,而不是<
while(left<=right){
int mid=(left+right)/2;
if(nums[mid]==target) return mid;
if(nums[mid]<target){
//左边有序,mid是最大,那target肯定在右边了
//注意点2:必须是<=
if(nums[left]<=nums[mid]) left=mid+1;
//右边有序
else {
//注意点3:必须是<
if(nums[right]<target) right = mid - 1;
else left=mid+1;
}
continue;
}
if(target<nums[mid]){
//左边有序,mid是最大,那target肯定在左边了
//注意点4:必须是<=
if(nums[left]<=nums[mid]){
//注意点5:必须是<=
if(nums[left]<=target) right=mid-1;
else left=mid+1;
}
//右边有序,那么target肯定还在左边小的那部分
else right=mid-1;
}
}
return -1;
}
}