LeetCode 34 Find the first and last solution of an element

Question details

Given an integer array nums arranged in ascending order, and a target value target. Find the start and end positions of the given target value in the array.

The time complexity of your algorithm must be O(log n) level.

If there is no target value in the array, return [-1, -1].

Example 1:

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

The purpose of writing this question is to exercise one's dichotomous ability, so we still need to write more dichotomies, after all, logN.
Secondly, the sub-problems of this question can be very useful questions.

Analysis and answers

The idea of ​​the question can be written like this

二分查找:
    如果nums[mid]>target :
    	则target在另一边
    如果nums[mid]<target :
    	则target在另一边
    如果nums[mid]==target:
    	则找到了目标值,于是便来寻找其第一个与第二个
    	在左区间find第一个target
    	在右区间find最后的target
    	return
    
    return

Here, the binary search is used to find the first and last targets in the left and right intervals, so the total is logN.
The advantage of my way of writing is that it is a bit smaller than the logN of finding the first one and finding the last one directly, but the order of magnitude is still the same.

For the idea of ​​finding the first and last one, look at the code directly

	public int findFirstTarget(int[] nums,int target){
    
    
        int l = 0, r = nums.length-1;
        int mid = l + ((r-l)>>1);
        while(l<=r){
    
    
            if(nums[mid]>target){
    
    
                r = mid - 1;
            }
            else if(nums[mid]<target){
    
    
                l = mid + 1;
            }
            else{
    
    
                if(mid==l || nums[mid-1]!=target){
    
    
                    return mid;
                }
                r = mid - 1;
            }
            mid = l + ((r-l)>>1);
        }
        return -1;//未找到
    }

The last one found here is consistent with the above idea, just slightly modify it.
In fact, I feel that the above can be used to do the following questions. After all, logN finds the first or last one, it is still necessary to practice.

The overall code is:

	public int[] searchRange(int[] nums, int target) {
    
    
        //思路这样
        //首先二分查找,修改l与r
        //一旦mid找到,则两边分别找第一个target和最后一个target
        int l=0, r=nums.length-1;
        while(l<=r){
    
    
            int mid = l+ ((r-l)>>1);
            if(nums[mid]<target){
    
    
                l = mid+1;
            }
            else if(nums[mid]>target){
    
    
                r = mid-1;
            }
            else {
    
    
                //target==nums[mid],则左区间寻找第一个target,右区间寻找最后一个target
                //都是二分法查找
                int ll = l, lr = mid;
                int lmid = ll + ((lr-ll)>>1);
                while(ll<=lr){
    
    
                    if(nums[lmid]<target){
    
    
                        ll = lmid +1;
                    }
                    else{
    
    
                        if(lmid==ll || nums[lmid-1]!=target){
    
    
                            break;
                        }
                        lr = lmid -1;
                    }
                    lmid = ll + ((lr-ll)>>1);
                }

                int rl = mid, rr = r;
                int rmid = rl + ((rr-rl)>>1);
                while(rl<=rr){
    
    
                    if(nums[rmid]>target){
    
    
                        rr = rmid - 1;
                    }
                    else{
    
    
                        if(rmid==rr || nums[rmid+1]!=target){
    
    
                            break;
                        }
                        rl = rmid + 1;
                    }
                    rmid = rl + ((rr-rl)>>1);
                }
                return new int[]{
    
    lmid,rmid};
            }
        }
        return new int[]{
    
    -1,-1};
    }

Guess you like

Origin blog.csdn.net/qq_34687559/article/details/110001055