二分思路:
我们可以从题目得知,拿到的数组中只有一个元素会出现一次,其余的都是两次出现,那么我们可以确定这个数组的长度一定是奇数。
此时我们通过二分找到这个数组的中项,它可能是两个相同元素的第一项或是第二项,我们就需要用一下两行代码来判断
if (mid + 1 < nums.size()&&nums[mid] == nums[mid + 1])
else if (mid - 1 >= 0 &&nums[mid] == nums[mid - 1])
(前面的mid+1和mid-1是为了防止溢出)
然后我们将这两个相同元素看作为一个元素,去找这个元素左右两边的数组哪一个是奇数长度,就能知道单独出现的元素在哪一边,
就用这两堆代码:
int rr = r - mid - 1;
if (rr % 2 == 1) {
l = mid + 2;
} else {
r = mid - 1;
}
int rr = r - mid;
if (rr % 2 == 1) {
l = mid + 1;
} else {
r = mid - 2;
}
}
以此类推,我们就能找到单独出现的元素了
当然,会有直接在某一次找中项中找到单独出现的元素的情况,那么就需要加上break了
附上完整代码:
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int mid = 0, l = 0, r = nums.size() - 1;
while (r >= l) {
mid = (l + r + 1) / 2;
if (mid + 1 < nums.size()&&nums[mid] == nums[mid + 1]) {
int rr = r - mid - 1;
if (rr % 2 == 1) {
l = mid + 2;
} else {
r = mid - 1;
}
} else if (mid - 1 >= 0 &&nums[mid] == nums[mid - 1]) {
int rr = r - mid;
if (rr % 2 == 1) {
l = mid + 1;
} else {
r = mid - 2;
}
}
else break;
}
return nums[mid];
}
};