540. 有序数组中的单一元素
给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。
请你找出并返回只出现一次的那个数。
题目
示例 1
输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2
示例 2
输入: nums = [3,3,7,7,10,11,11]
输出: 10
答案
二分法
^的运算法则: 只有在两个比较的位不同时其结果是 1,否则结果为 0 即“两个输入相同时为 0,不同则为 1”!
思路:
声明对撞指针
left/right
根据二分法比较
target
,找到对应下标 mid- while 循环条件:
while (left <= right) {}
nums[mid]
对比nums[mid ^ 1]
- 相等则
left = mid + 1
- 不相等
right = mid
- while 循环条件:
var singleNonDuplicate = function(nums) {
let left = 0
let right = nums.length -1
// 常规二分法,不断取【中间值】去尝试。
// 直到left <= right 的值为止,说明中间值只剩一个,无法继续二分
while (left < right) {
// 动态取中间:
let mid=left+Math.floor((right-left)/2);
// 满足条件:当前元素【中间值】等于下一项,说明找到问题元素,记录下标
if(nums[mid] == nums[mid ^ 1]){
left = mid + 1
}else{ // 不满足:继续二分
right = mid
}
/*
console.log('mid',mid,'left',left,'right',right)
mid 4 left 0 right 4
mid 2 left 0 right 2
mid 1 left 0 right 1
mid 0 left 1 right 1
*/
}
return nums[left]
};
var nums = [1,1,2,3,3,4,4,8,8]
console.log(singleNonDuplicate(nums))
暴力
var singleNonDuplicate = function (nums) {
//排序后直接两两比较
nums = nums.sort((a, b) => a - b);
for (let i = 0; i < nums.length; i += 2) {
if (nums[i] != nums[i + 1]) return nums[i];
}
};
var nums = [1,1,2,3,3,4,4,8,8]
console.log(singleNonDuplicate(nums))