【Leetcode】540. Single Element in a Sorted Array

题目地址:

https://leetcode.com/problems/single-element-in-a-sorted-array/

给定一个从小到大排好序的数组 A A A,除了其中一个数字只出现了一次外,每个数字都出现了两次,要求找到那个只出现了一次的数字。

法1:位运算。一路异或一遍即可。代码如下:

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int res = 0;
        for (int n : nums) {
            res ^= n;
        }
        
        return res;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

比下文更好的二分思路参考https://blog.csdn.net/qq_46105170/article/details/113623636

法2:二分。考虑将区间二分后如何判断那个唯一的数应该在哪个半边。设二分中点为 m m m,区间左右端点分别为 l l l r r r,那么区间中比 A [ m ] A[m] A[m]大的数的个数可以这样计算:如果 A [ m ] = A [ m + 1 ] A[m]=A[m+1] A[m]=A[m+1],那么个数是 r − m − 1 r-m-1 rm1;否则个数是 r − m r-m rm。而由于除了那个落单的数以外,其他数都是两两配对的,所以如果比 A [ m ] A[m] A[m]大的数的个数是偶数个,那么那个唯一的数一定在左半边,否则在右半边。这样就可以缩小范围了。代码如下:

public class Solution {
    public int singleNonDuplicate(int[] nums) {
        int l = 0, r = nums.length - 1;
        while (l < r) {
            int m = l + (r - l >> 1);
            if (nums[m] == nums[m + 1]) {
                int larger = r - m - 1;
                // 如果比A[m]大的数是偶数个,则答案在左边,且不能是A[m],所以令r = m - 1;
                // 如果比A[m]大的数是奇数个,则答案在右边,且不能是A[m],所以令l = m + 2;
                if (larger % 2 == 0) {
                    r = m - 1;
                } else {
                    l = m + 2;
                }
            } else {
            	// 此时nums[m] != nums[m + 1],则nums[m + 1] > nums[m]。
                int larger = r - m;
                // 如果比A[m]大的数是偶数个,则答案在左边,且可能是A[m],所以令r = m;
                // 如果比A[m]大的数是奇数个,则答案在右边,且不可能是A[m](因为题目保证答案是唯一的),所以令r = m - 1;
                if (larger % 2 == 0) {
                    r = m;
                } else {
                    l = m + 1;
                }
            }
        }
        
        return nums[l];
    }
}

时间复杂度 O ( log ⁡ n ) O(\log n) O(logn),空间 O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值