LeetCode——Search for a Range

本文详细介绍了如何在已排序的整数数组中使用改进的二分查找方法,快速定位给定目标值的起始和结束位置,确保算法复杂度为O(log n),并提供了两种实现方式:幂扩展法和递归二分搜索法。

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

Given a sorted array of integers, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

» Solve this problem


最简单的思路是:在普通的二分查找到目标值之后,向左右扩展。

但是,如果是线性扩展(每次递增1或者递减1),算法有可能会退化到O(n)。

例如,在“8 8 8 8 8 8 8 8 8 8 8 8 8 ... 8”中搜“8”。


改进的方法,可以采用幂扩展,第一次递增1,第二次递增2,第三次递增4,直到某次搜索到的值不是target,再处理:

int expand(int idx) {
    k = 0;
    while (A[idx + 2^k] == target) k++;
    if (k != 0) {
        return find(idx + 2^(--k));
    }
    else {
        return idx;
    }
}


另外一种方法就是在普通的二分查找后,对左右两个区间继续进行二分搜索。

在这个过程中记录目标值出现的最左位置和最右位置。

class Solution {
public:
    vector<int> searchRange(int A[], int n, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        begin = end = -1;
        find(A, 0, n - 1, target);
        vector<int> ans;
        ans.push_back(begin);
        ans.push_back(end);
        return ans;
    }
    
private:
    int begin = -1;
    int end = -1;
    
    void find(int A[], int l, int r, int target) {
        if (l > r) {
            return;
        }
        int mid = (l + r) >> 1;
        if (A[mid] == target) {
            if (mid < begin || begin == -1) {
                begin = mid;
            }            
            if (mid > end) {
                end = mid;
            }
            find(A, l, mid - 1, target);
            find(A, mid + 1, r, target);
        }
        else if (A[mid] < target) {
            find(A, mid + 1, r, target);
        }
        else {
            find(A, l, mid - 1, target);
        }
    }
};






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值