【力扣刷题练习】33. 搜索旋转排序数组

发布时间:2024年01月16日

题目描述:

整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为[4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题

题目解答:

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

        while (l < r) {
            int mid = l + r >> 1;
            if (nums[mid] >= target)
                r = mid;
            else
                l = mid + 1;
        }
        return nums[r] == target ? r : -1;
    }
};

题目思路:

应用二分查找的思路
首先获得容器数组的长度并且设置好l和r
第一个while循环的目的是反复比较从而找出变换前的最大元素位置(其实就是最后一个元素,因为数组默认升序)
接下来通过if else语句判断target元素比首元大还是小,如果更大的话说明在翻转后的前半段里,将l设置为0;反之则取后半段,将l设置为l++(即变换前首个元素位置,或者说最小的元素),同时将r的位置重新设置为数组尾部。
处理完上述过程,开始应用二分查找,通过比较mid位置元素与target元素的大小不断二分缩小查找空间。当mid位置元素大小大于等于target时说明target元素在mid左侧或刚好在该位置,故将r设置为mid,下次从左侧空间查找;反之,mid位置元素大小大于target时说明target元素在mid右侧,故将l设置为mid+1,下次从右侧空间查找。
最终若找到则返回该位置下标。

文章来源:https://blog.csdn.net/NaturalHarmonia/article/details/135521646
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。