`

Leetcode - Search for a Range

 
阅读更多
[分析]
思路1: 伪二分查找。若中间元素正好是target时,分四种小情况:1)左右边界也等于target时,当前这段就是要找的范围,可直接返回;2)只有左边界等于target,则右边界往左靠近一步;3)只有右边界等于target,则左边界往右靠近一步;4)左右边界均不等于target,则左右均往里逼近一步。容易看出在中间元素恰好是target时,算法退化为O(N)的。
思路2: 二分法依次查找target第一次出现和最后一次出现的位置。

[ref]
二分查找(Binary Search) 常见问题解决方法总结
http://blog.csdn.net/daniel_ustc/article/details/17307937
http://bangbingsyb.blogspot.com/2014/11/leetcode-search-for-range.html


public class Solution {
    // Method 2: O(logN)
    public int[] searchRange(int[] nums, int target) {
        int[] result = {-1, -1};
        if (nums == null || nums.length == 0)
            return result;
        result[0] = binarySearchFirst(nums, target);
        if (result[0] != -1) {
            result[1] = binarySearchLast(nums, target);
        }
        return result;
    }
    // 查找target在nums[]中第一次出现的下标,若找不到返回-1
    public int binarySearchFirst(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left < right) { // 此处不能有等号,否则可能在right=mid处死循环,考虑case:[1], 1
            mid = left + ((right - left) >> 1);
            if (target > nums[mid])
                left = mid + 1;
            else
                right = mid;
        }
        if (nums[left] == target)
            return left;
        return -1;
    }
    // 查找target在nums[]中最后一次出现的下标,若找不到返回-1
    public int binarySearchLast(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left + 1 < right) { // 循环只处理元素个数大于两个的情况,两个以下元素时可能在left=mid处死循环(两个元素时left==mid),考虑case:[1,1],1
            mid = left + ((right - left) >> 1);
            if (target < nums[mid])
                right = mid - 1;
            else
                left = mid;
        }
        if (nums[right] == target)
            return right;
        else if(nums[left] == target)
            return left;
        return -1;
    }
    
    // Method 1
    public int[] searchRange1(int[] nums, int target) {
        int[] result = {-1, -1};
        if (nums == null || nums.length == 0)
            return result;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] > target)
                right = mid - 1;
            else if (nums[mid] < target)
                left = mid + 1;
            else {
                if (nums[left] == nums[mid] && nums[mid] == nums[right]) {
                    result[0] = left;
                    result[1] = right;
                    return result;
                } else if (nums[left] == nums[mid]) {
                    right--;
                } else if (nums[right] == nums[mid]) {
                    left++;
                } else {
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics