1. 数组有N+M个数字, 数字的范围为1 ... N, 打印重复的元素, 要求O(M + N), 空间复杂度O(1)
设数组为a[N+M],
从a[0] 到 a[N+M-1],
对每个数字 a[i] , 如果 a[i]==a[a[i]-1], 则continue
如果 a[i]!=a[a[i]-1],则交换两者。
输出a[N]到a[N+M-1] //这就是结果。
一共有N+M个数字,就把这N+M个数字放到a[o]~a[N-1]里,1 就放在 a[0]里,2就放在a[1]里,a[i]就放在a[a[i]-1]里,遍历一遍后,a[N]~a[N+M-1]放的就是重复的。
例子:
N=5, M=3
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]
5 5 3 4 4 1 2 5 //原始
第一个数字a[0]=5要放到a[4]里,a[4]!=5,所以和a[4]交换。如果和a[4]相等就不用换了。
4 5 3 4 5 1 2 5
第二个数字a[1]=5要放到a[4]里,a[4]==5,所以不用和a[4]交换。
4 5 3 4 5 1 2 5
第三个数字a[2]=3,要放在a[2]里,所以不用换了。
4 5 3 4 5 1 2 5
第四个数字,a[3]=4,要放在a[3]里,也不用换了。
4 5 3 4 5 1 2 5
第五个数字,a[4]=5.不用换了
4 5 3 4 5 1 2 5
第六个数字,a[5]=1, 要放在a[0]里,交换。
1 5 3 4 5 4 2 5
第七个数字,a[6]=2, 要放在a[1]里,交换。
1 2 3 4 5 4 5 5
第八个数字,a[7]=5, 要放在a[4]里,不用交换了,因为a[4]已经是5了。
输出 a[N] 到 a[N+M-1] 即 : 4 5 5
代码:
static void Main(string[] args) { int[] num = {1, 7, 5, 7, 9, 1, 4, 8, 6, 0, 4, 2, 5, 2, 3}; int temp; int i = 14; while (i != 9) { temp = num[num[i]]; if (num[i] == temp) { Console.Write(num[i]); i--; } else { num[num[i]] = num[i]; num[i] = temp; } } Console.Read(); }