leetcode 153. Find Minimum in Rotated Sorted Array 、154. Find Minimum in Rotated Sorted Array II 、33...

这4个题都是针对旋转的排序数组。其中153、154是在旋转的排序数组中找最小值,33、81是在旋转的排序数组中找一个固定的值。且153和33都是没有重复数值的数组,154、81都是针对各自问题的版本1增加了有重复数值的限制条件。

153、154都需要考虑是否旋转成和原数组一样的情况,特别的,154题还需要考虑10111和11101这种特殊情况无法使用二分查找。

33、81则不用考虑这些情况。

找最小值的题主要是利用最小值小于他前一个位置的数,同时也小于后一个位置的数

 

start是前面升序的最后一个,end是后面升序的第一个, 只剩两个时,end就代表了那个最小值

153. Find Minimum in Rotated Sorted Array 

class Solution {
public:
    int findMin(vector<int>& nums) {
        int start = 0;
        int end = nums.size() - 1;
        int mid;
        if(nums[start] < nums[end])
            return nums[start];
        while(start + 1 < end){
            mid = start + (end - start)/2;
            if(nums[mid] < nums[start])
                end = mid;
            else
                start = mid;
        }
        return nums[end];
    }
};

 

 

154. Find Minimum in Rotated Sorted Array II

class Solution {
public:
    int findMin(vector<int>& nums) {
        int start = 0;
        int end = nums.size() - 1;
        int mid = start + (end - start)/2;
        if(nums[start] < nums[end])
            return nums[start];
        if(nums[start] == nums[end] && nums[start] == nums[mid]){
            int min_num = INT_MAX;
            for(int i = 0;i < nums.size();i++){
                if(nums[i] < min_num)
                    min_num = nums[i];
            }
            return min_num;
        }
        while(start + 1 < end){
            mid = start + (end - start)/2;
            if(nums[mid] < nums[start])
                end = mid;
            else
                start = mid;
        }
        return nums[end];
    }
};

 

33. Search in Rotated Sorted Array

这个题和剑指上旋转数组求最小值有点不一样,还是用二分查找的方法做,但条件判断较为繁琐。首先明确一点,无论怎么分,左右两侧总有一个是有序的,并且一般情况左侧是大的数,右侧是小的数。mid小于target的时候,相当于要找一个更大的数,所以想法是先排除一般情况下小的数,如果start < mid,证明这是个升序,那只可能在右侧;如果start > mid,证明右侧是升序,只要和最大的比较,也就是end,如果比end小,说明数字在右侧,如果比end大,说明数字在左侧,因为比最大的都大了。

总体上就是当target大于mid的时候,就去比较可能出现大数的左侧区间,如果是升序,那就能排除;如果左侧区间不是升序,则右侧是升序,需要拿这个升序的最大值和mid进行比较来确定下一个区间

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty())
            return -1;
        int start = 0;
        int end = nums.size() - 1;
        int mid;
        while(start + 1 < end){
            mid = start + (end - start)/2;
            if(nums[mid] == target)
                return mid;
            else if(nums[mid] < nums[end]){
                if(nums[mid] < target && nums[end] >= target)
                    start = mid;
                else
                    end = mid;
            }
            else{
                if(nums[mid] > target && nums[start] <= target)
                    end = mid;
                else
                    start = mid;
            }
        }
        if(nums[start] == target)
            return start;
        if(nums[end] == target)
            return end;
        return -1;
    }
};

自己的写法:

其实是可以使用mid - 1,mid+1的,因为之前做了nums[mid] == target的判断,这说明mid不可能等于target,所以可以去掉。

最需要注意的是,在判断单调区间时,start、end与target的比较一定是<=或者>=,必须考虑边界相等的情况

总体的思路就是:判断单调区间,然后判断target属于不属于这个区间,属于就在这个区间找,不属于就去另一个区间找。判断属于不属于,就是拿target与这个区间的边界进行判断。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty())
            return -1;
        int start = 0,end = nums.size() - 1;
        while(start + 1 < end){
            int mid = start + (end - start)/2;
            if(nums[mid] == target)
                return mid;
            else if(nums[start] < nums[mid]){
                if(target < nums[mid] && nums[start] <= target)
                    end = mid - 1;
                else
                    start = mid + 1;
            }
            else{
                if(target > nums[mid] && nums[end] >= target)
                    start = mid + 1;
                else
                    end = mid - 1;
            }
        }
        if(nums[start] == target)
            return start;
        if(nums[end] == target)
            return end;
        return -1;
    }
};

 

 

 

81. Search in Rotated Sorted Array II

这个题与Search in Rotated Sorted Array不同在于,这个题里面可能包含重复的数字。

代码上的区别主要是在进行单调区间判断的时候,即如果start或者end与mid的值相等的情况要单独列出来,列出来的方式是start++,mid--

Search in Rotated Sorted Array直接else其实是包括了=这种情况,但是因为本身数组不存在相等的,所以忽略了这个问题。

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        if(nums.empty())
            return false;
        int start = 0;
        int end = nums.size() - 1;
        int mid;
        while(start + 1 < end){
            mid = start + (end - start)/2;
            if(nums[mid] == target)
                return true;
            else if(nums[mid] < nums[end]){
                if(nums[mid] < target && nums[end] >= target)
                    start = mid;
                else
                    end = mid;
            }
            else if(nums[mid] > nums[end]){
                if(nums[mid] > target && nums[start] <= target)
                    end = mid;
                else
                    start = mid;
            }
            else
                end--;
        }
        if(nums[start] == target)
            return true;
        if(nums[end] == target)
            return true;
        return false;
    }
};

http://www.cnblogs.com/grandyang/p/4325840.html

 

704. Binary Search

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty())
            return -1;
        int start = 0;
        int end = nums.size() - 1;
        int mid;
        while(start + 1 < end){
            mid = start + (end - start)/2;
            if(nums[mid] == target)
                return mid;
            else if(nums[mid] < target)
                start = mid;
            else
                end = mid;
        }
        if(nums[start] == target)
            return start;
        if(nums[end] == target)
            return end;
        return -1;
    }
};

 

转载于:https://www.cnblogs.com/ymjyqsx/p/10730810.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值