leetcode——Search for a Range 二分查找重复数字

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].

      二分查找一般都是找到某一个特定的数字,通过比较中间的数值和目标数值的大小(target>mid 目标数值就在右边 target<mid 目标数值就在左边  如果相等就直接返回mid)可以获得目标函数在哪个部分。但是这道题目要求求出目标数字出现的区间(大于等于一个),这就涉及到当找到目标数字时,需要判断目标数字的左右是否还有目标数值,如果有,再在两边搜索,左边有的话就在左边找第一个出现目标数值的index,右边有的话就在右边找最后一个出现目标数值的index,这样我们又想到可以利用递归在左右搜索第一个出现或最后一个出现的目标数值。

     int findFirst(vector<int>& nums,int target,int low,int high){
         if(low>high) return -1; \\递归到low》high 即所有数列中的数都遍历过没有return 即没有找到目标数值,返回-1
         int mid=(low+high)/2;
             if(nums[mid]==target){   \\当找到第一个target
                 if(((mid-1)>=0&&nums[mid-1]!=target)||mid==0) return mid; \\看它左边是否到头或者是否有目标数值,如果有目标数值,则第一个目标数                                                                                                                                                                值在左边,否则为第一个目标数值
                 else high=mid-1;
             }
             else if(target<nums[mid]) high=mid-1;             
             else low=mid+1;
         return findFirst(nums,target,low,high);
     }

  没有找到相等数值的时候就和一般二分查找一样。

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
         vector<int> res;
         if(nums.empty()) return res;
         int low=0;
         int high=nums.size()-1;
         int first=findFirst(nums,target,low,high);
         int last=findLast(nums,target,first,high);
         res.push_back(first);
         res.push_back(last);
         return res;
    }
    
     int findFirst(vector<int>& nums,int target,int low,int high){
         if(low>high) return -1;
         int mid=(low+high)/2;
             if(nums[mid]==target){
                 if(((mid-1)>=0&&nums[mid-1]!=target)||mid==0) return mid;
                 else high=mid-1;
             }
             else if(target<nums[mid]) high=mid-1;
             else low=mid+1;
         return findFirst(nums,target,low,high);
     }
     int findLast(vector<int>& nums,int target,int low,int high){
         if(low>high) return -1;
         int mid=(low+high)/2;
         if(nums[mid]==target){
             if(((mid+1)<nums.size()&&nums[mid+1]!=target)||mid==nums.size()-1) return mid;
             else low=mid+1;
         }
         else if(target>nums[mid]) low=mid+1;
         else high=mid-1;
         return findLast(nums,target,low,high);
     }


};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值