刷题(10)leetcode 540 --binary search

540. Single Element in a Sorted Array

You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once.Return the single element that appears only once.Your solution must run in O(log n) time and O(1) space.

是medium。如果没有最后一句要求就是easy了。第一反应肯定是brute force, 因为就算brute force, time complexity 也就只有O(n),, 然而,这里需要O(logn). 一看到O(logn), 第一反应就是binary search。这个也就给接下来解题指定了方向。

比较好理解的一种方法就是去掉mid和(mid -1 or mid +1)以后左右两边的section是不是even。

class Solution {

    public int singleNonDuplicate(int[] nums) {

        int left = 0, right = nums.length - 1;

        while(left<right) {

            int mid = left + (right - left)/2;

            boolean rightHalfIsEven = (right - mid) % 2 == 0;

            if(nums[mid] == nums[mid+1]) {

                if(rightHalfIsEven) {

                    left = mid + 2;

                } else {

                    right = mid - 1;

                }

            } else if(nums[mid] == nums[mid -1]){

                if(rightHalfIsEven) {

                    right = mid - 2;

                } else {

                    left = mid + 1;

                }

            } else {

                return nums[mid];

            }

        }

        return nums[left];

    }

}

最后注意一下corner case,就是最后返回nums[left]那边。

我看有人解释怎么判断l<r还是l<=right:

Easy heuristic:

if you discard mid for the next iteration (i.e. l = mid+1 or r = mid-1) then use while (l <= r).

if you keep mid for the next iteration (i.e. l = mid or r = mid) then use while (l < r)

还有就是:

if you are returning from inside the loop, use left <= right

if you are reducing the search space, use left < right and finally return a[left]

可以作为参考。但是对我们这个solution都不适用哈哈哈哈。所以还是以具体问题具体分析,多用corner case test比较好。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容