解题思路:
二分搜索,维持一个个数为奇数的数组,直到仅剩一个元素。循环每次删除中间点和或于其左或于其右的重复数字(中间点恰为单一元素时直接输出),然后判断剩下的左半段和右半段哪边有奇数个元素,所求单一元素就在哪边。
代码:
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int mid, l = 0, r = nums.size()-1;
while(r - l > 0) {
mid = (l + r) / 2;
if(nums[mid] == nums[mid-1]) { //中间点与其左元素重复时
if((mid-1) % 2 == 1) r = mid-2; //左半段有奇数个元素
else l = mid+1; //右半段有奇数个元素
}
else if (nums[mid] == nums[mid+1]) { //中间点与其右元素重复时
if(mid % 2 == 1) r = mid-1; //左半段有奇数个元素
else l = mid+2; //右半段有奇数个元素
}
else l = r = mid; //中间点恰为单一元素时
}
return nums[l]; //返回最后仅剩的单一元素
}
};
如题目要求,时间复杂度O(logn),空间复杂度O(1)。