Search in Rotated Sorted Array-Leetcode

26 篇文章 0 订阅

题意:Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
思路:原始的在有序数组寻找target元素的方法就是采用二分查找。这道题的不同在于将有序数组在一个未知位置进行了旋转,所以不能简单的按照原始方法来寻找。
如果有序数组进行了反转,则数组的最后一个元素小于数组的第二个元素,并且在数组的中间某个位置的其后一个元素的值将小于当前元素的值。在找准旋转的位置,我们可以在这两段中进行二分查找。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty()) return -1;
        int n=nums.size()-1;
        if(nums[0]<nums[n]) //数组未进行旋转,在整个数组的范围内进行二分查找
        {
           int low=0;
           int high=n;
           int middle=0;
           while(low<=high){
               middle=(low+high)/2;
               if(nums[middle]==target) return middle;
               else if(nums[middle]<target){
                   low=middle+1;
               }
               else high=middle-1;
           }
           return -1;
        }
        //数组进行了旋转,首先找出中间的分界点j,将数组分成[0~j-1],[j-n]两部分再进行二分查找
        else{
            int i=-1;
            int j=0;
            while(nums[++i]<=nums[++j]);//在找出中间nums[i]>nums[j]的位置
            //target不在[0~j-1]范围内
            if(target<nums[0]){
                int low=j;
                int high=n;
                int middle=0;
                while(low<=high){
                    middle=(low+high)/2;
                    if(nums[middle]==target) return middle;
                    else if(nums[middle]<target){
                      low=middle+1;
                    }
                    else high=middle-1;
                }
                return -1;
            }
             //target不在[j~n]范围内
            else{
                int low=0;
                int high=i;
                int middle=0;
                while(low<=high){
                    middle=(low+high)/2;
                    if(nums[middle]==target) return middle;
                    else if(nums[middle]<target){
                      low=middle+1;
                    }
                    else high=middle-1;
                }
                return -1;
            }
        }
    }
};

这种方法思路正确,AC。后来,笔者又在网上找到了更好的方法,这里贴出代码,学习一下。

public class Solution {  
    public int search(int[] A, int target) {  
        int l = 0;  
        int r = A.length - 1; 
        //直接按照二分查找 
        while (l <= r) {  
            int mid = (l + r) / 2;  
            if (target == A[mid]) return mid;  
            //三种可能有序的情况(一定有一种成立),选择有序的情况进行二分查找
            //[l~r]是有序的
            if (A[l] <= A[r]) {  
                if (target < A[mid]) r = mid - 1;  
                else l = mid + 1;  
            } else if (A[l] <= A[mid]) {  //[l~mid]是有序的
                if (target > A[mid] || target < A[l]) l = mid + 1;  
                else r = mid - 1;  
            } else {  //[mid+1~r]是有序的
                if (target < A[mid] || target > A[r]) r = mid - 1;  
                else l = mid + 1;  
            }  
        }  
        return -1;  
    }  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值