posts - 35,comments - 0,views - 3100

33.搜索旋转排序数组

题目描述

image

题解

为了设计一个复杂度为 O(logn) 的算法,可以采用二分的思想,但是题给数组只是一个部分有序的数组,更准确一点,应该是两个有序数组拼接而成的部分有序数组,唯一出现乱序的地方就是两个数组的拼接处。为了使用二分查找算法,我们必须确定中位点mid位于哪一个有序数组中。这里提供一个简单的思路,我们将nums[mid]nums[0]作比较,由于数组中的元素互不相等,因此:

1.nums[mid] > nums[0]:那么左半部分[left, mid-1]有序
2.nums[mid] < nums[0]:那么右半部分[mid+1, right]有序

如果target==nums[mid],查找成功,退出。

在上述条件1的情况下,如果:target的值介于[nums[0], nums[mid]) 之间,则往左半部分遍历,否则往右半部分遍历。

在上述条件2的情况下,如果:target的值介于(nums[mid], nums[n-1]] 之间,则往右半部分遍历,否则往左半部分遍历。
代码如下:

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

该题的思想在于:每次二分时,将一个较大的部分有序的数组转化为一个较小的有序数组和一个较小的部分有序数组。

posted on   sc01  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示