您现在的位置是:首页 >技术杂谈 >算法与数据结构(搜索旋转排序数组)网站首页技术杂谈

算法与数据结构(搜索旋转排序数组)

a_j58 2025-03-24 12:01:02
简介算法与数据结构(搜索旋转排序数组)

题目

思路

找到数组中与target相同的数,并且返回它的下标,我的第一反应就是直接循环遍历它,然后将数组中的每个值与target比较,若相同,直接返回下标。如果遍历完所有数组之后,依旧没有找到相同的数,就直接返回-1。但题目要求必须用logn的时间复杂度解决此问题,因此我们可以换个思路。

用二分法来对题目进行搜索。因为二分法只能应用于有序的数组,而本题不能确保数组所有部分都是有序的。

我们将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环.。

解题过程

首先我们可以定义left以及right为二分查找定义索引。

While(left <= right) 在这个循环下进行left和right的移动。

定义mid索引为left和right的中间值

先进行判断,若target值等于nums[mid],则直接返回mid。

因为将数组一分为二,两部分肯定有一个有序。

(1)如果左边有序,则再次进行判断,若target在left与mid之间,则right =mid-1,否则left =mid+1;

(2)如果右边有序,则进行判断,若target在mid和right之间,则left =mid+1,否则right = mid -1;

最后如果在数组中没有找到target,则返回-1。

这里我引用力扣中的图能更加清晰地说明情况。

代码

class Solution {
public:
    //将数组一分为二,其中一定一部分是有序的,另一部分可能有序,可能无序
    //有序部分用二分查找,无序部分再一分为二
    int search(vector<int>& nums, int target) 
    {
        int left = 0;
        int right = nums.size()-1;
        while(left <= right)
        {
            int mid = (left+right)/2;
            if(target == nums[mid])
                return mid;
            //如果左边为有序区间
            if(nums[left] <= nums[mid])
            {
                //target在左边有序区间内
                if(target >= nums[left] && target < nums[mid])
                    right = mid -1;
                else
                    left = mid + 1;
            }
            //如果右边为有序区间
            else
            {
                //target在右边有序区间内
                if(target > nums[mid] && target <= nums[right])
                    left = mid +1;
                else
                    right = mid - 1;
            }
        }
        return -1;
    }
};

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。