剑指offer—不修改数组找出重复的数字go语言版

题目描述:

给定一个长度为n+1的数组nums,数组中所有的数均在1∼n 的范围内,其中 n≥1。

请找出数组中任意一个重复的数,但不能修改输入的数组。

样例

给定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。

返回 2 或 3。

思考题:如果只能使用 O(1)的额外空间,该怎么做呢?

题目思路:

该题目主要使用二分查找的思路和抽屉原理,即在1~n范围内有n+1个数则必定有重复的数。那么如果不在原数组上进行修改并且不新建数组的情况下,就是用二分法。以数值大小进行分割,查看两边哪边有多出来的数那就在那一边继续进行分割直到找到重复的数为止。该题目需要注意的情况有:

1、数组不包含重复的数字

2、无效的输入(空数组等)

3、中间值的判定,小心数组越界以及一边包含中间值的情况下另一边不能包含。

代码实现:

func duplicateInArray(nums []int) int {
	var middle int
	var start = 1
	var end = len(nums) - 1
	if nums == nil || len(nums) == 1 {
		return -1
	}
	for start <= end {
		middle = (end-start)/2 + start
		choose := search(nums, start, middle)
		if start == end {
			return start
		}
		if choose == 1 {
			end = middle
		} else {
			start = middle + 1
		}
	}
	return middle
}

func search(nums []int, start, middle int) int {
	num := 0
	for i := 0; i < len(nums); i++ {
		if nums[i] <= middle && nums[i] >= start {
			num++
		}
	}
	if num <= middle-start+1 {
		return 0
	} else {
		return 1
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值