1. 程式人生 > >[leetcode][34] Find First and Last Position of Element in Sorted Array

[leetcode][34] Find First and Last Position of Element in Sorted Array

數組 -o tin num ive new algorithm target gre

34. Find First and Last Position of Element in Sorted Array

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

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]

解析

思路很簡單,二分查找,找兩次,第一次找到目標值,第二次找目標值+1,就可以定位出目標值的範圍。

參考答案

自己寫的:

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] res = new int[2];
        if (nums.length == 0) {
            res[0] = -1;
            res[1] = -1;
            return res;
        }
        int lo = binarySearch(nums, target);
        if (nums[lo] != target) {
            res[0] = -1;
            res[1] = -1;
            return res;
        }
        if (nums.length == 1) {
            res[0] = lo;
            res[1] = lo;
            return res;
        }
        int hi = binarySearch(nums, target+1);
        res[0] = lo;
        res[1] = nums[hi] == target ? hi : hi-1;
        return res;
    }
    
    public int binarySearch(int[] nums, int target) {
        int lo = 0;
        int hi = nums.length - 1;
        while(lo < hi) {
            int mid = (lo + hi) / 2;
            if (nums[mid] < target) {
                lo = mid + 1;
            } else {
                hi = mid;
            }
        }
        return lo;
    }
}

別人寫的:

public class Solution {
    public int[] searchRange(int[] A, int target) {
        int start = Solution.firstGreaterEqual(A, target);
        if (start == A.length || A[start] != target) {
            return new int[]{-1, -1};
        }
        return new int[]{start, Solution.firstGreaterEqual(A, target + 1) - 1};
    }

    //find the first number that is greater than or equal to target.
    //could return A.length if target is greater than A[A.length-1].
    //actually this is the same as lower_bound in C++ STL.
    private static int firstGreaterEqual(int[] A, int target) {
        int low = 0, high = A.length;
        while (low < high) {
            int mid = low + ((high - low) >> 1);
            //low <= mid < high
            if (A[mid] < target) {
                low = mid + 1;
            } else {
                //should not be mid-1 when A[mid]==target.
                //could be mid even if A[mid]>target because mid<high.
                high = mid;
            }
        }
        return low;
    }
}

雖然對二分法已經很熟悉了,但是在一些邊界上還是了解不夠,這裏我去了length-1為hi,這樣查找的數組上邊界還要加判斷,別人是取了length為hi。比如在【2,2】裏面插找3,上面一種方法返回的是1,後面一種返回的是2,在【2,3】裏面查找3,兩種方法返回的都是1。總結下來就是,當查找的數超出上邊界時,第一種方法返回右邊界下標,第二種方法仍然可以返回不小於目標值的最小值。用第二種方法就不用對結果加判斷了,更優雅簡單.

[leetcode][34] Find First and Last Position of Element in Sorted Array