leetcode 34. 在排序數組中查找元素的第一個和最後一個位置 & 劍指 Offer 53 - I. 在排序數組中查找數字 I

【題目】34. 在排序數組中查找元素的第一個和最後一個位置

給定一個按照升序排列的整數數組 nums,和一個目標值 target。找出給定目標值在數組中的開始位置和結束位置。
你的算法時間複雜度必須是 O(log n) 級別。
如果數組中不存在目標值,返回 [-1, -1]。

示例 1:

輸入: nums = [5,7,7,8,8,10], target = 8
輸出: [3,4]

示例 2:

輸入: nums = [5,7,7,8,8,10], target = 6
輸出: [-1,-1]

【解題思路1】線性查找

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] targetRange = {-1, -1};
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == target) {
                targetRange[0] = i;
                break;
            }
        }
        if (targetRange[0] == -1) {
            return targetRange;
        }
        for (int j = nums.length-1; j >= 0; j--) {
            if (nums[j] == target) {
                targetRange[1] = j;
                break;
            }
        }
        return targetRange;
    }
}

【解題思路2】二分法

找到 target的左邊起始點,和 target + 1的起始點,這樣二分法就統一成一個函數了

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int a = search(nums,target);
        int b = search(nums,target+1);
        if(a==nums.length||nums[a]!=target) //這表明數組中不存在target
            return new int[]{-1,-1};
        return new int[]{a,b-1}; //否則數組中存在target,則b-1是最後一個target的元素索引
    }
    
    //該二分查找nums中第一個>=t的元素位置
    int search(int[] nums, int t) {
        int l = 0,r = nums.length;
        while(l<r){
            int m = (l+r)>>>1;
            if(nums[m]<t)
                l = m+1;
            else
                r = m;
        }
        return l;
    }
}

拆開來寫,找target的左端,再找target右端

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int right = lower_bound(nums, target);
        int left = higher_bound(nums, target);
        return new int[]{left, right};
    }
    private int lower_bound(int[] a, int v){
        int l = 0;
        int r = a.length - 1;
        int res = -1;
        while(l <= r){
            int mid = l + ((r-l)>>1);
            if(a[mid] < v){
                l = mid + 1;
            }else if(a[mid] > v){
                r = mid - 1;
            }else{
                res = mid;
                l = mid + 1;
            }
        }
        return res;
    }
    private int higher_bound(int[] a, int v){
        int l = 0;
        int r = a.length - 1;
        int res = -1;
        while(l <= r){
            int mid = l + ((r-l)>>1);
            if(a[mid] > v){
                r = mid - 1;
            }else if(a[mid] < v){
                l = mid + 1;
            }else{
                res = mid;
                r = mid - 1;
            }
        }
        return res;
    }
}

【題目】劍指 Offer 53 - I. 在排序數組中查找數字 I

統計一個數字在排序數組中出現的次數。

示例 1:

輸入: nums = [5,7,7,8,8,10], target = 8
輸出: 2

示例 2:

輸入: nums = [5,7,7,8,8,10], target = 6
輸出: 0

限制:
0 <= 數組長度 <= 50000

注意:本題與主站 34 題相同(僅返回值不同)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章