【二分查找】LeetCode 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];
}
}