算法题汇总

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();
}
原文地址:https://www.cnblogs.com/xiaxianfei/p/5461808.html