题目:
给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n **位上的数字。
算法:
方法一:位运算
利用异或
func singleNonDuplicate(nums []int) int {
ans := 0
for i := range nums {
ans = ans ^ nums[i]
}
return ans
}
方法二: 二分查找
假设只出现一次的元素位置为x,如果没有x,则每个偶数位的数和奇数位的数相等,x出现之后,在x之后的位置,变成了奇数位的位置和偶数位的位置相等。
利用二段性进行二分查找。
func singleNonDuplicate(nums []int) int {
left, right := 0, len(nums) - 1
n := len(nums)
for left < right {
mid := (left + right) >> 1
// 下标分布: 偶 奇 x 奇 偶
// mid为偶数下标时,只能left = mid + 1,因为nums[mid + 1] != nums[mid]可能是x,或者x右侧,所以right = mid
if mid % 2 == 0 {
if mid + 1 < n && nums[mid + 1] == nums[mid] {
left = mid + 1
} else {
right = mid
}
} else {
// 下标分布: 偶 奇 x 奇 偶
// 奇数位时,如果nums[mid - 1] != nums[mid],可能是x或者x右侧,所以只能right = mid 而不能right = mid -1
if mid - 1 >= 0 && nums[mid - 1] == nums[mid] {
left = mid + 1
} else {
right = mid
}
}
}
return nums[left]
}