#62 Search in Rotated Sorted Array

本文介绍了一种使用二分查找法解决旋转有序数组中目标值搜索问题的方法。文章首先阐述了问题背景,即在一个未知旋转点的有序数组中查找特定目标值,并详细解释了如何通过两次二分查找找到目标值的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

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.

Example

For [4, 5, 1, 2, 3] and target=1, return 2.

For [4, 5, 1, 2, 3] and target=0, return -1.

Challenge 

O(logN) time

题目思路:

题目要求用O(logN)的时间,明显就是二分法的思路。但是这种rotate sorted的array怎么用binary search呢?我的想法可能有些复杂(因为要用two-pass才解出来),是先用binary search找到整个数组A的最小值的index,假设是sidx,然后我把A再接上一个A,这样从sidx~sidx+A.size()-1这一段坐标,数值都是正常sorted的。这样用传统的二分法就可以找到target了。

这题需要注意的是2点:

1. 用binary search找最小值时,最小值靠左的情况有两种:A[mid] < A[l](这说明最大值在左边,最小值在包括mid的左边),A[mid] < A[r](这说明mid往右是正常sorted的)。

2. sidx~sidx+A.size()-1有部分index是超出A.size() - 1的,我用%A.size()就可以得到它在0~A.size()-1的index范围内的相应index。

Mycode(AC = 27ms):

class Solution {
    /** 
     * param A : an integer ratated sorted array
     * param target :  an integer to be searched
     * return : an integer
     */
public:
    int search(vector<int> &A, int target) {
        // write your code here
        if (A.size() == 0) return -1;
        
        // find the index of minimum number in A
        int l = 0, r = A.size() - 1, sidx = -1;
        while (l + 1 < r) {
            int mid = (l + r) / 2; // 2
            
            if (A[mid] < A[l] || A[mid] < A[r]) {
                r = mid;
            }
            else {
                l = mid;
            }
        }
        
        sidx = A[l] <= A[r]? l : r;
        
        // concatenate 2 A's, so that index start ~ end
        // is fully ordered
        int start = sidx, end = sidx + A.size() - 1;
        while (start <= end) {
            int mid = (start + end) / 2;
            if (A[mid % A.size()] == target) {
                return mid % A.size();
            }
            else if (A[mid % A.size()] < target) {
                start = mid + 1;
            }
            else {
                end = mid - 1;
            }
        }
        
        return -1;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值