【每日题解】540. 有序数组中的单一元素

给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。请你找出并返回只出现一次的那个数。

你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。

示例 1:

输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2

示例 2:

输入: nums =  [3,3,7,7,10,11,11]
输出: 10

思路

本来是O(n)循环遍历一圈就可以,但是题目要求时间复杂度必须是 O(log n) ,所以要采用二分法,同时空间复杂度要满足 O(1),所以我们要采用一种不通过比较的方法找到只出现一次的数字。

通过观察和理解题意,因为其他数字都是成对出现,并且只有我们要找的数字出现一次,因此 nums 的总长度一定是奇数,因此我们一定能找到唯一的 mid 值。同时我们只要比较 mid 和它左边或右边的数字是否相等,就能找到出现一次的数字在 mid 左边还是右边。

因为如果 mid 是奇数,则应该和它右边的数字相比较,因为成对出现的数字一定会形成偶数长度。如果 mid 是偶数则和它左边的数字相比较。然后更新端点即可。

代码(C++)

class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int low = 0, high = nums.size() - 1;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            if (nums[mid] == nums[mid ^ 1]) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return nums[low];
    }
};

1. 异或操作符 (^)

异或操作符 (^) 是一种位操作符,用于对两个二进制数的每一位进行比较。如果两个位相同,结果为 0,如果两个位不同,结果为 1。例如:

  • 0 ^ 0 = 0

  • 0 ^ 1 = 1

  • 1 ^ 0 = 1

  • 1 ^ 1 = 0

在整数上使用异或操作符时,结果是两个整数的每一位进行异或操作后的结果。例如:

  • 5 ^ 1 = 4 (二进制表示:101 ^ 001 = 100

  • 6 ^ 1 = 7 (二进制表示:110 ^ 001 = 111

2. mid ^ 1 的作用

在二分查找或其他算法中,mid 通常表示当前的中间索引。mid ^ 1 的作用是根据 mid 的奇偶性来选择相邻的索引:

  • 如果 mid 是偶数,mid ^ 1 会得到 mid + 1

  • 如果 mid 是奇数,mid ^ 1 会得到 mid - 1

这是因为:

  • 对于偶数 midmid 的二进制表示的最后一位是 0,所以 mid ^ 1 会将最后一位从 0 变为 1,即 mid + 1

  • 对于奇数 midmid 的二进制表示的最后一位是 1,所以 mid ^ 1 会将最后一位从 1 变为 0,即 mid - 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值