leetcode 540. 有序数组中的单一元素 (中等)
给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。
示例 1:
输入: [1,1,2,3,3,4,4,8,8]
输出: 2
方法1:
由于数组是有序的,而且要找的数只有一个,那么该数肯定在偶数位,长度为1的数组单独解决
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int l = nums.size();
if (l == 1) return nums[0];
for (int i = 0; i < l; i += 2) {
if (nums[i] != nums[i + 1]) {
return nums[i];
}
}
return 0;
}
};
时间复杂度O(n)
方法2:
二分查找法 判断当前中点数字是否出现两次,有可能和前一位相同,有可能和后一位相同,然后判断左子数组大小是否为偶数,以此确定下一步搜寻的子数组。
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
int mid, leftPair;
while (l < r) {
mid = (l + r) / 2;
if (nums[mid] == nums[mid + 1]) {
leftPair = (mid - l) % 2;
if (leftPair == 0) {
l = mid + 2;
}
else {
r = mid - 1;
}
}
else if (nums[mid] == nums[mid - 1]) {
leftPair = (mid - 1 - l) % 2;
if (leftPair == 0) {
l = mid + 1;
}
else {
r = mid - 2;
}
}
else {
return nums[mid];
}
}
return nums[l];
}
};
时间复杂度O(logn)
方法3:
异或
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int l = nums.size();
int res = 0;
for (int i = 0; i < l; i++) {
res ^= nums[i];
}
return res;
}
};
时间复杂度O(n)