搜索旋转排序数组

题目:

整数数组 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) 的算法解决此问题。

示例:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4

解题思路:

因为题目要求时间复杂度为 O(log n),所以本题运用二分搜索法的思路来实现

 1.相当于数组是由两个升序序列组成的,第一个序列中最小的元素比第二个序列中最大的元素还要大,所以在二分查找的过程中需要额外加上判断条件;
 2.若nums[mid]>=nums[left],当且仅当target >= nums[l] && target < nums[mid]时,target在[left,mid]范围内,此时将right移动到mid-1
 3.相反,若nums[mid]>=nums[left],当且仅当target > nums[mid] && target <= nums[r]时,target在[mid,right]范围内,此时将left移动到mid+1

源代码如下:

int search(vector& nums, int target) {
        int l = 0, r = nums.size() -1;
        
        while (l <= r)
        {
            int mid =( l + r) / 2;
            if (target == nums[mid]) return mid;
            //说明mid在第一个序列中
            if (nums[l] <= nums[mid])
            {
                //判断target是否在数组的第一个升序序列中
                if (target >= nums[l] && target < nums[mid])
                    r = mid-1;
                else
                    l = mid+1;
            }
            //说明mid已经在数组的第二个升序序列中了
            else
            {
                //判断target是否在第二个升序序列中
                if (target > nums[mid] && target <= nums[r])
                    l = mid +1;
                else
                    r = mid -1;
            }
        }
        //没找到,返回-1
        return -1;
    }

你可能感兴趣的:(算法,数据结构,leetcode,排序算法,c++)