287.寻找重复数

218 阅读1分钟

题目:
给定一个包含 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
}