作者:愤怒的黑皮_165 | 来源:互联网 | 2024-12-28 13:14
来源:力扣(LeetCode),链接:https://leetcode-cn.com/problems/single-element-in-a-sorted-array。题目要求在仅包含整数的有序数组中,找到唯一出现一次的元素,并确保算法的时间复杂度为O(logn)和空间复杂度为O(1)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-element-in-a-sorted-array
题目描述
给定一个仅由整数组成的有序数组,其中每个元素都会恰好出现两次,唯有一个数只会出现一次。请找出并返回这个唯一出现一次的元素。
解决方案必须满足以下条件:
示例 1:
输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2
示例 2:
输入: nums = [3,3,7,7,10,11,11]
输出: 10
提示:
- 数组长度范围:1 <= nums.length <= 10^5
- 元素值范围:0 <= nums[i] <= 10^5
解题思路
本题的关键在于如何在限制的时间和空间复杂度内解决问题。由于时间复杂度要求是 O(log n),二分查找法是一个理想的解决方案。
我们可以通过观察发现,唯一元素 a 的左边必然有偶数个元素,因此 a 的索引必然是偶数。此外,对于 a 左边的偶数索引 i,nums[i] == nums[i + 1];对于 a 右边的偶数索引 j,nums[j] == nums[j - 1]。基于此规律,我们可以使用二分查找来定位唯一元素。
具体步骤如下:
- 初始化左右边界:left = 0,right = 最大的偶数索引。
- 计算中间的偶数索引 mid(如果是奇数则减 1 转换为偶数)。
- 如果 nums[mid] == nums[mid + 1],说明唯一元素在 mid 右侧,更新 left = mid + 2。
- 否则,唯一元素可能在 mid 或其左侧,更新 right = mid。
- 循环直到 left >= right,此时 left 即为唯一元素的索引。
代码实现
class Solution {
public:
int singleNonDuplicate(vector& nums) {
int left = 0, right = nums.size() - 1;
if (right % 2 != 0) right--;
while (left int mid = (left + right) / 2;
if (mid % 2 != 0) mid--;
if (nums[mid] == nums[mid + 1])
left = mid + 2;
else
right = mid;
}
return nums[left];
}
};
运行结果