区间查找

时间:2022-06-08
本文章向大家介绍区间查找,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

给定一个排序数组nums(nums中有重复元素)与目标值target,如果 target在nums里出现,则返回target所在区间的左右端点下标,[左端点, 右端 点],如果target在nums里未出现,则返回[-1, -1]。 LeetCode 34. Search for a Range

思考

1.可否直接通过二分查找,很容易同时求出目标target所在区 间的左右端点? 2.若无法同时求出区间左右端点,将对目标target的二分查找 增加怎样的限制条件,就可分别求出目标target所在区间 的左端点与右端点?

算法设计

查找区间左端点时,增加如下限制条件: 当target == nums[mid]时,若此时mid == 0或nums[mid-1] < target,则说明mid即 为区间左端点,返回;否则设置区间右端点为mid-1。

查找区间右端点时,增加如下限制条件: 当target == nums[mid]时,若此时mid == nums.size() – 1或 nums[mid + 1] > target ,则说明mid即为区间右端点;否则设置区间左端点为mid + 1

流程:

int left_bound(std::vector<int> &nums, int target){
    int begin = 0;
    int end = noms.size() -1 ;
    while(begin <= end){
        int mid = (begin + end) / 2;
        if(target == nums[mid]){
            if(mid == 0 || target > nums[mid-1]){
                return mid;
            }
            begin = mid + 1;
        }
        else if(target < nums[mid]){
            end = mid -1;
        }
        else if(target > nums[mid]){
            begin = mid +1;
        }
    }
    return -1;
}
区间右端点
int right_bound(std::vector<int> &nums,int target){
    int begin = 0;
    int end = nums.size() -1;
    while(begin <= end){
        int mid =( begin + end )/2;
        if(target == mid){
            if(mid = nums.size()-1 || nums[mid+1] > target){
                return mid;
            }
            begin = mid +1;
          }
        else if(target < nums[mid]){
            end = mid -1;
        }
        else if(target > nums[mid]){
            begin = mid+1;
        }
     }
return -1;
}
leetcode测试
class Solution{
public:
    std::vector<int> searchRange(std::vector<int>&nums, int target){
        std::vector<int> result;
        result.push_back(left_bound(nums,target));
        result.push_back(right_bound(nums,target));
        return result;
    }
};

int main(){
    int test[] = {5,7,7,8,8,8,8,10};
    std::vector<int> nums;
    Solution solve;
    for(int i = 0;i< 8;i++){
        nums.push_back(test[i]);
    }
    for(int i= 0;i< 12;i++){
        std::vector<int> result = solve.searchRange(nums,i);
        printf("%d : [%d,%d]n",i, result[0],result[i]);
    }
    return 0;
}