题目:
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。
假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。
你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。
算法:
方法一:二分查找
left, right := 1, n
选择mid,nums中小于等于mid的元素个数最多只有mid个,则小于mid的数中没有重复值
func findDuplicate(nums []int) int {
left, right := 1, len(nums) - 1
for left < right {
mid := (left + right) / 2
count := 0
for i := range nums {
if nums[i] <= mid {
count ++
}
}
if count > mid {
right = mid
} else {
left = mid + 1
}
}
return left
}
方法二:位运算
统计1~n的所有数的二进制中,每一位上1的个数,记为x
统计nums[0]~nums[n - 1] 的所有数的二进制中,每一位上1的个数,记为y
如果某一位x大于y,,则说明该位是属于重复的数字,该位记为1,统计所有的位数,得到结果ans
func findDuplicate(nums []int) int {
bitNum := 0
n := len(nums) - 1
for n >> bitNum != 0 {
bitNum ++
}
ans := 0
for bit := 0; bit <= bitNum; bit ++ {
x, y := 0, 0
for i := range nums {
if nums[i] & (1 << bit) != 0 {
x ++
}
if i > 0 && (i & (1 << bit) != 0) {
y ++
}
}
if x > y {
ans = ans | (1 << bit)
}
}
return ans
}