目录
- 1.题目
- 2.思路
- 3.代码实现(Java)
1.题目 给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。
请你找出并返回只出现一次的那个数。
你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。
示例 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 <= 105
0 <= nums[i] <= 105
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/single-element-in-a-sorted-array
2.思路 (1)二分搜索
思路参考该 LeedCode 用户题解。
题目要求算法的时间复杂度为 O(logn),所以首先想到二分搜索,但是关键在于如何对数组 nums 进行二分。
【LeetCode|LeetCode_二分搜索_中等_540.有序数组中的单一元素】① 由题目可知,有序数组中每个元素都会出现两次,唯有一个数只会出现一次,以数组 [1, 1, 2, 3, 3, 4, 4, 8, 8] 为例,元素 2 只出现了一次;
② 如果将元素 2 去掉,那么数组中的所有元素均出现了2 次,并且可以组成 4 个相等数对:[1, 1]、[3, 3]、[4, 4]、[8, 8],但是 2 的出现,破坏了原来的相等数对(并且数组长度也由偶数变成了奇数):[1, 1]、[2 3]、[3, 4]、[4, 8]、[8, ];
③ 此时我们可以发现:元素 2 之前的相等数对仍然存在,而之后的相等数对被破坏,所以我们将这一点作为二分的依据!
3.代码实现(Java)
//思路1————二分搜索
class Solution {
public int singleNonDuplicate(int[] nums) {
int length = nums.length;
int left = 0;
int right = length / 2;
while (left < right) {
int mid = (left + right) / 2;
int index = mid * 2;
if (nums[index] != nums[index + 1]) {
//当前数对的两个元素不相等,故只出现一次的数在左边
right = mid;
} else {
//当前数对的两个元素相等,故只出现一次的数在右边
left = mid + 1;
}
}
return nums[left * 2];
}
}
推荐阅读
- LeetCode|LeetCode_栈_中等_735.行星碰撞
- LeetCode|LeetCode_双指针_中等_611.有效三角形的个数
- LeetCode|LeetCode算法刷题目录(Java)
- leetcode|【Leetcode】刷题题单记录
- LeetCode|《LeetCode力扣练习》剑指 Offer 10- I. 斐波那契数列 Java
- 前端面试|JS数组乱序的几种方法
- 力扣|力扣打卡之最小栈
- dp|最近写过的dp题单(持续更新)
- 算法面试冲刺|Leetcode 算法面试冲刺 热题 HOT 100 刷题(337 338 347 394 399)(六十八)