题目链接: https://leetcode.com/problems/single-element-in-a-sorted-array/description/
Description
Given a sorted array consisting of only integers where every element appears twice except for one element which appears once. Find this single element that appears only once.
Example 1:
Input: [1,1,2,3,3,4,4,8,8]
Output: 2
Example 2:
Input: [3,3,7,7,10,11,11]
Output: 10
Note: Your solution should run in O(log n) time and O(1) space.
解题思路
方法一:
最简单的方法,从左到右遍历一遍数组,比较当前元素与前后两个元素值,若都不相同,则返回该元素值;否则,继续往后遍历。
时间复杂度 O(n)
,空间复杂度 O(1)
方法二:
利用二分的思想,每次判断数组中间元素的下标和该元素值与左右两元素值之间的关系。因为只有一个单个元素,因此数组长度为奇数,记下标为 [0, 2k]
。对于当前元素 nums[mid]
,分为如下几种情况,
nums[mid] != nums[mid - 1]
且nums[mid] != nums[mid + 1]
=> 目标元素mid
为偶数且nums[mid] == nums[mid - 1]
=> 单个元素在数组下标区间[0, mid - 1]
mid
为奇数且nums[mid] == nums[mid + 1]
=> 单个元素在数组下标区间[0, mid - 1]
mid
为偶数且nums[mid] == nums[mid + 1]
=> 单个元素在数组下标区间[mid + 1, 2k]
mid
为奇数且nums[mid] == nums[mid - 1]
=> 单个元素在数组下标区间[mid + 1, 2k]
分别对应的例子,
# 数组下标 [0, 4], mid = 2, nums[mid] = 2
[1, 1, 2, 3, 3]
# 数组下标 [0, 8], mid = 4, nums[mid] = nums[mid - 1] = 3
[1, 1, 2, 3, 3, 4, 4, 5, 5]
# 数组下标 [0, 6], mid = 3, nums[mid] = nums[mid + 1] = 3
[1, 1, 2, 3, 3, 4, 4]
# 数组下标 [0, 8], mid = 4, nums[mid] = nums[mid + 1] = 3
[1, 1, 2, 2, 3, 3, 4, 5, 5]
# 数组下标 [0, 6], mid = 3, nums[mid] = nums[mid - 1] = 2
[1, 1, 2, 2, 3, 4, 4]
根据目标元素所在区间,更新 left
和 right
值,直到找到满足第一个条件的元素值即为结果。
时间复杂度 O(log n)
,空间复杂度 O(1)
Code
方法一:
class Solution {
public:
int singleNonDuplicate(vector<int> &nums) {
int res = -1;
for (int i = 0; i < nums.size(); ++i) {
if ((i - 1 < 0 || nums[i] != nums[i - 1]) &&
(i + 1 >= nums.size() || nums[i] != nums[i + 1])) {
res = nums[i];
break;
}
}
return res;
}
};
方法二:
class Solution {
public:
int singleNonDuplicate(vector<int> &nums) {
int res = -1;
int mid, left = 0, right = nums.size() - 1;
while (left <= right) {
mid = (left + right) >> 1;
if ((mid - 1 < 0 || nums[mid] != nums[mid - 1]) &&
(mid + 1 >= nums.size() || nums[mid] != nums[mid + 1])) {
res = nums[mid];
break;
} else if ((mid % 2 == 0 && nums[mid] == nums[mid - 1]) ||
(mid % 2 == 1 && nums[mid] == nums[mid + 1])) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return res;
}
};