面试题3: 数组中重复的数字(Java实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37129433/article/details/87949278

数组中重复的数字

题意:
在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组为{2,3,1,0,2,5,3},那么对于的输出是重复的数字2或者3。

题解:
首先是空间复杂度o(n),时间复杂度o(n)的算法。这个算法不足以拿到offer。直接开一个o(n)的arr辅助数组,并初始化为0,遍历numbers,每次把arr[numbers[i]]++。如果arr[numbers[i]]>=2,则说明numbers[i]重复了。直接返回便是。然后重点谈一下时间复杂度o(n),空间复杂度o(1)的算法。这个算法需要点思维。首先我们需要明白,如果该数组排好序,且没有重复的话那么numbers[i] = i,而现在这个有重复,那么会出现位置使得numbers[i]不等于i, 那么扫描numbers,当扫描到i时,如果numbers[i] != i 那么判断numbers[i] == number[numbers[i]]?如果等于的话那么就代表numbers[i]重复了,返回。如果不等于的话,就交换numbers[i]和numbers[numbers[i]],还原numbers[i]中的数字。建议模拟一下该算法。
java代码:

class Solution {
	// Parameters:
	// numbers: an array of integers
	// length: the length of array numbers
	// duplication: (Output) the duplicated number in the array number,length of
	// duplication array is 1,so using duplication[0] = ? in implementation;
	// Here duplication like pointor in C/C++, duplication[0] equal *duplication in
	// C/C++
	// 这里要特别注意~返回任意重复的一个,赋值duplication[0]
	// Return value: true if the input is valid, and there are some duplications in
	// the array number
	// otherwise false
	public boolean duplicate(int numbers[], int length, int[] duplication) {
		if (length <= 1 || numbers == null) { //这个是必须要加的,如果如果没加的话offer有点难
			return false;
		}
		for (int i = 0; i < length; i++) {
			while(numbers[i] != i) {
				if(numbers[i] == numbers[numbers[i]]) {
					duplication[0] = numbers[i];
					return true;
				}
				int temp = numbers[i];
				numbers[i] = numbers[temp];
				numbers[temp] = temp;
			}
		}
		return false;
	}
}

拓展:
这个算法是否也意味着,对于大小为n的数组,没有重复元素,value的范围从0~n-1。就可以用时间复杂度o(n),空间复杂度o(1)给他解决掉。这个点还是挺不错的。

如果有什么问题,或者有更加优秀的算法。欢迎留言,互相学习。

猜你喜欢

转载自blog.csdn.net/qq_37129433/article/details/87949278