算法-找出数组中重复的数字

本文来自于剑指Offer,是个人对剑指Offer的学习记录。

题目:在一个长度为n的数组里,所有的数字元素都在0到n-1的范围内,数组中有些数字是重复的,但是不知道有几个数字重复了,也不知道重复了几次。请找出数组中任意一个重复的数字。例如输入长度为7的数组{1,2,3,0,4,2,3},那么重复的数字应该是2或3。

最简单的方式应该是利用set,这种情况下时间复杂度是O(n),空间复杂度也是O(n)。

剑指Offer上有一个比较好的思路,因为数组中所有的元素都在0到n-1之间,所以,如果没有重复元素,那么从小到大排好序的数组中,每个下标对应的值应该跟下标一致。如果有重复元素,假设有数组为nums, 下标为i,int n = nums[i],那么一定存在i != n,而且nums[n] == n,所以我们就要找到这样一个值就行。

在寻找的过程中,我们不需要排序,只需要将数字n放到它应该对应的位置上,直到找到一个数字n不等于其下标i,而且有nums[n] == n。下面是代码

public boolean getRepeat(int[] nums) {
		if(nums == null || nums.length <= 1) {
			return false;
		}
		for(int i = 0; i < nums.length; i++) {
			while(nums[i] != i) {
				int n = nums[i];
				if(nums[i] == nums[n]) {
					System.out.println(nums[i]);
					return true;
				}
				nums[i] = nums[i] + nums[n];
				nums[n] = nums[i] - nums[n];
				nums[i] = nums[i] - nums[n];
			}
		}
		return false;
	}

因为数字交换最多只需要进行n-2次,然后按顺序比较即可,所以时间复杂度是O(n),因为没有开辟额外的内存空间,所以空间复杂度是O(1).

发布了19 篇原创文章 · 获赞 6 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/kanglupeng/article/details/103918532