【二分查找】LeetCode 540. 有序数组中的单一元素

发布时间 2023-05-07 08:36:21作者: Frodo1124

题目链接

540. 有序数组中的单一元素

思路

假如不存在单个的元素,那么在奇数位置上总是成对元素的第一个元素,偶数位置上总是成对元素的第二个元素,但是如果加入了单个元素呢?

我们可以看到在单个元素的左边这个特点没有变化,但是在单个元素的右边,奇数位置上总是成对元素的第二个元素,偶数位置上总是成对元素的第一个元素

也就是说,如果单个元素在 \(mid\) 左边,那么

\[\left\{ \begin{aligned} & nums[mid] = nums[mid + 1], mid 为奇数, \\ & nums[mid] = nums[mid - 1], mid 为偶数. \end{aligned} \right. \]

如果单个元素在 \(mid\) 右边,那么

\[\left\{ \begin{aligned} & nums[mid] = nums[mid - 1], mid 为奇数, \\ & nums[mid] = nums[mid + 1], mid 为偶数. \end{aligned} \right. \]

利用这个区别,我们就知道应该收缩左边界还是右边界了。

代码

class Solution {
    public int singleNonDuplicate(int[] nums) {
        if(nums.length == 1){
            return nums[0];
        }

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

        while(left <= right){
            int mid = (right - left) / 2 + left;
            if(mid % 2 == 0){
                if(mid + 1 < nums.length && nums[mid] == nums[mid + 1]){
                    left = mid + 1;
                }else{
                    right = mid - 1;
                }
            }else{
                if(mid - 1 >= 0 && nums[mid] == nums[mid - 1]){
                    left = mid + 1;
                }else{
                    right = mid - 1;
                }
            }
        }

        return nums[left];
    }
}