Leetcode#34 Search for a Range

 

题目描述:

Given an array of integers nums sorted in ascending order, 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].

 

分析:

Search for a range:

pre: a inc list of int and the target val
post: the range for the val in the list of [-1,-1]

与普通的二分法要进行改进:

 

    当mid的值与val值相同时,要从head->mid和从mid->tail中选出新的前后值

这里采取先选择head值,重复操作,直到head和tail对应的数据等于目标值val,退出循环。

 

class Solution:
    def searchRange(self, nums, val):
        head = 0
        tail = len(nums)-1
        mid = (head+tail)//2
        while head < tail:
            flag = 0 
            if ( nums[mid] < val ):
                head = mid+1
                mid = (head+tail)//2
            elif nums[mid] > val :
                tail = mid-1
                mid = (head+tail)//2
            elif nums[head] < val :
                mid = (head+mid)//2
            elif nums[tail] > val :
                mid = (tail+mid)//2+1
            else :
                break 
        ans = []
        if ( head >= len(nums) or nums[head] != val ):
            ans.append(-1)
            ans.append(-1)
        else :
            ans.append( head)
            ans.append( tail )
        return ans
        

 

另一思路:分两次寻找,分别寻找目标范围的head index和tail index

 

C++代码实现如下:

寻找head index和tail index的主要区别在于:1. mid的计算,向下取整或向上取整(目的是在不同的更新情况下达到收敛)。 2. 当nums[mid] == target时,如果寻找head index, 则更新right;如果是在寻找tail index,则更新left

 

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int left = 0, right = nums.size()-1 ;
        vector<int> ans ;
        
        // 寻找head index(nums的最左侧等于target的索引)
        while( left < right ){
            int mid = left + (right-left)/2 ;
            if( nums[mid] >= target ){
                right = mid ;
            }else{
                left = mid+1 ;
            }
        }
        if( nums.size()>0 && nums[left] == target )
            ans.push_back( left ) ;
        else
            ans.push_back( -1 ) ;

        left = 0 ;
        right = nums.size()-1 ;
        // last position, how to end the loop
        // 寻找tail index(nums的最右侧等于target的索引)
        while( left < right ){
            int mid = left + (right-left)/2 +1 ;
            if( nums[mid] > target ){
                right = mid-1 ;
            }else{
                left = mid ;
            }
        }
        if( nums.size()>0 && nums[left] == target )
            ans.push_back( left ) ;
        else
            ans.push_back( -1 ) ;
        return ans ;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值