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

链接:  http://leetcode.com/problems/search-for-a-range/  

题解:

考察Binary Search的结束条件。 使用两次Bianry Search,一次搜索左边界,一次搜索右边界,最后需要比较一下左边界是否 <= 右边界,假如条件不成立则target不在数组中。

Time Complexity - O(n), Space Complexity - O(1)

public class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] res = {-1, -1};
        if(nums == null || nums.length == 0)
            return res;
        int lolo = 0, lohi = nums.length - 1, hilo = 0, hihi = nums.length - 1;
        
        while(lolo <= lohi) {                   //try find left end
            int mid = lolo + (lohi - lolo) / 2;
            if(nums[mid] < target)
                lolo = mid + 1;
            else
                lohi = mid - 1;
        }
        
        while(hilo <= hihi) {                   //try find right end
            int mid = hilo + (hihi - hilo) / 2;
            if(nums[mid] > target)
                hihi = mid - 1;
            else
                hilo = mid + 1;
        }
        
        if(lolo <= hihi) {                     //if target exist
            res[0] = lolo;
            res[1] = hihi;
        }
        
        return res;
    }
}

二刷:

Java:

要使用两次binary search来分别搜索target值的最左端和最右端。最后需要判断一下求出来的left 是否<= right,否则 [1], 1这样的test case会过不了

public class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] res = {-1, -1};
        if (nums == null || nums.length == 0) {
            return res;
        }
        int lo = 0, hi = nums.length - 1;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if (target > nums[mid]) {
                lo = mid + 1;
            } else {
                hi = mid - 1;
            }
        }
        int left = lo;
        lo = 0;
        hi = nums.length - 1;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if (target >= nums[mid]) {
                lo = mid + 1;
            } else {
                hi = mid - 1;
            }
        }
        int right = hi;
        if (left <= right) {
            res[0] = left;
            res[1] = right;
        }
        return res;
    }
}

三刷:

这回写得比较奇怪。原理都一样,都是使用两次binary search,但是改变了一些变量和条件。

要注意搜索左边界时,遇到mid = target时我们hi = mid - 1,最后返回的边界index是lo。搜索右边界时,遇到mid = target我们lo = mid + 1,最后返回的边界index是hi。也需要判断一下没有搜索到的case,这就是代码里的两个独立if语句的作用。

Java:

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

Update:

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

  

原文地址:https://www.cnblogs.com/yrbbest/p/4436310.html