[Leetcode] 33. Search in Rotated Sorted Array 解题报告

这篇博客介绍了如何解决LeetCode上的33题——在一个已旋转的有序数组中搜索目标值。文章详细阐述了两种解题思路:1) 两次二分查找,首先找到旋转点,然后在确定的区间内进行普通二分查找;2) 一次二分查找,通过比较中位数和边界值判断目标值所在区间。代码示例展示了具体的实现方法,并提醒读者在确定递增区间后可直接使用标准二分查找以提高效率。此外,博主还指出当数组允许重复元素时,需要采用不同的解法,如LeetCode 81题的解法。

题目

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.

思路

对于排序之后的数据结构,二分查找是不二法则。本题的关键就在于如何针对旋转之后的排序数组进行二分查找。考虑到数组中没有重复元素(注意这一前提十分关键),可以提供两种思路:

1、两次二分查找:第一次二分查找的目标是找出数组具体在哪个位置做了旋转,这个可以简单地通过比较nums[mid]和它的相邻元素的大小实现。第二次二分查找就简单了:先判断待查找值在左半部分还是右半部分,然后调用普通的二分查找进行查询。

2、一次二分查找:由于数组中没有重复元素,所以思路1中的第一次二分查找其实是不必要的。设中位数为nums[mid],则一次二分查找的思路如下:

             1)如果nums[mid] == target,则直接返回mid;

             2)如果nums[mid] < nums[right],则说明从mid到right之间是严格递增的。此时可以方便地判断target是否在这一递增区间内:如果是,则在这一递增区间内查找;否则就在另外一个递增区间内找。

             3)如果nums[mid] > nums[right],则说明从left到mid之间是严格递增的。此时可以方便地判断target是否在这一递增区间内:如果是,则在这一递增区间内查找;否则就在另外一个递增区间内找。

             注意在下面的代码中,即使已经判断出某一区间为严格递增区间了,我们还是用了自己设计的针对旋转排序数组的查找方法。事实上,此时我们可以直接调用标准的二分查找方法,速度应该会更快一些(建议读者自己设计并实现)。

代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.size() == 0)    return -1;
        int left = 0, right = nums.size() - 1;
        while(left <= right)
        {
            int mid = left + (right - left) / 2;
            if(nums[mid] == target)
            {
                return mid;
            }
            else if(nums[mid] < nums[right])    // the right part is increasing
            {
                if(nums[mid] < target && target <= nums[right])
                    left = mid + 1;             // might be improved by binarySearch
                else
                    right = mid - 1;
            }
            else                                // the left part is increasing
            {
                if(nums[left] <= target && target < nums[mid])
                    right = mid - 1;            // might be improved by binarySearch
                else
                    left = mid + 1;
            }
        }
        return -1;
    }
};


Follow up

如果允许数组中有重复元素呢?此时就不能通过判断相互大小每次使搜索空间减半了。具体解法请参考Leetcode 81。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值