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
提示:
1 <= nums.length <= 105
0 <= nums[i] <= 105
题解
此题可以直接使用位运算进行异或,但是题目要求满足O(log n)
时间复杂度和 O(1)
空间复杂度。
所以选择二分法解决
我们读题可以发现给定我们的是一个有序数组,由此可以得出,如果一个元素出现了两次,那么这两次是相邻的
所以我们取中间的数,然后对他两边的数进行判断如果他和两边的数都不相同,那么这个数就是只出现了一次的数字
同时我们还能知道两个条件
-
如果中间的数下标是偶数(以数组下标来判断),且这个数与左端的数相等,只出现一次的数一定在他的左端,反之也如此
-
如果是奇数,且这个数与左端的数相等,只出现一次的数一定在他的右端,反之也是如此
代码
class Solution {
public int singleNonDuplicate(int[] nums) {
int n = nums.length;
int l = 0, r = n - 1;
while(l < r){
int mid = l + r >> 1;
if(mid % 2 == 0){
if(mid + 1 < n && nums[mid] == nums[mid + 1]){
l = mid + 1;
}else{
r = mid;
}
}else{
if(mid - 1 >= 0 && nums[mid] == nums[mid - 1]){
l = mid + 1;
}else{
r = mid;
}
}
}
return nums[r];
}
}