leetcode 34. 在排序数组中查找元素的第一个和最后一个位置

虽然只是一道中等难度的题目,但是看了官方的解答,有很精彩的地方,但是总体代码写得不算优雅。

class Solution {
    // returns leftmost (or rightmost) index at which `target` should be
    // inserted in sorted array `nums` via binary search.
    private int extremeInsertionIndex(int[] nums, int target, boolean left) {
        int lo = 0;
        int hi = nums.length;

        while (lo < hi) {
            int mid = (lo + hi) / 2;
            if (nums[mid] > target || (left && target == nums[mid])) {
                hi = mid;
            }
            else {
                lo = mid+1;
            }
        }

        return lo;
    }

    public int[] searchRange(int[] nums, int target) {
        int[] targetRange = {-1, -1};

        int leftIdx = extremeInsertionIndex(nums, target, true);

        // assert that `leftIdx` is within the array bounds and that `target`
        // is actually in `nums`.
        if (leftIdx == nums.length || nums[leftIdx] != target) {
            return targetRange;
        }

        targetRange[0] = leftIdx;
        targetRange[1] = extremeInsertionIndex(nums, target, false)-1;

        return targetRange;
    }
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/zai-pai-xu-shu-zu-zhong-cha-zhao-yuan-su-de-di-yi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

精彩的是用一个boolean类型变量提高了代码重用性,但是不好在主函数里还要对返回值进行检查,这不是应该在辅助函数做好的事情吗?看了另一位同学(代码有错,修改了一下)

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;
                r = 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;
                l = mid + 1;
            }
        }
        return res;
    }
}

这样的辅助函数就很不错,但是与官方解答相比两个辅助函数重复度很高,可以综合两者写出更优雅的代码

public class SearchRange2 {
    public int[] searchRange(int[] nums, int target) {
        int left = findBound(nums, target, true);
        int right = findBound(nums, target, false);
        return new int[]{left, right};
    }

    private int findBound(int[] nums, int target, boolean left){
        int low = 0;
        int high = nums.length - 1;
        int res = -1;
        while (low <= high){
            int mid = low + ((high - low) >> 1);
            if (nums[mid] == target){
                res = mid;
            }
            if (nums[mid] > target || (left && (nums[mid] == target))){
                high = mid - 1;
            }else {
                low = mid + 1;
            }
        }
        return res;
    }
}

代码明显短了也更好看了,综合leftbound和rightbound两个函数时由于两者更新res操作不在一个地方所以单独用一个if进行res更新。由于减少了代码量猜测占用JVM方法区的内存变小了,导致内存消耗也减少了。

你可能感兴趣的:(leetcode,leetcode,java,binary,search)