算法中的奇技淫巧

最近在各个论坛有看到关于算法的一些奇技淫巧,有点感受,在这里记录一下

1. 一个数组中,只有一个数只出现了一次,其他的都出现了两次,找出只出现了一次的数,比如 [1,2,3,4,5,4,3,2,1],其中,没有重复的就是5
看到这种题,大概第一个想法是利用hash表吧,每次存储时,记录次数,最后再遍历看看谁只出现了一次。
然鹅,我看到有一种算法,真真真真真是太简单了
我们都学过位运算吧,那么,异或运算就是解题的关键咯!!!我们都知道异或运算中,如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。0异或所有的数都等于那个数的本身。再根据结合律和交换律本题是不是就得解啦:

1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 4 ^ 3 ^ 2 ^ 1 = (1 ^ 1) ^ (2 ^ 2) ^ (3 ^ 3) ^ (4 ^ 4) ^ 5 = 0 ^ 0 ^ 0 ^ 0 ^ 5 = 5

		int[] a = {1,2,3,4,5,4,3,2,1};
		int temp = a[0];
		for (int i = 1; i < a.length; i++) {
			temp = temp ^ a[i];
		}
		System.out.println("The result is " + temp);

是不是简单明了!!!!而且它的复杂度是O(1)

那么我们来提高一下下,请听题:

  1. 已知有一个大小为11的数组,里面装有1-10的数,其中只有一个重复,其它的数字只出现了一次,那么怎么找到这个数呢???
    在这个数组里面肯定有1-10这10个数,剩下一个数也在这里面,假如1-10这十个数异或出来是N,设我们要求的数为n,那么,最终这11个数异或的结果为N ^ n。
    已知:1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 ^ 9 ^ 10 = N
    则: 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 ^ 9 ^ 10 ^ n = N ^ n
    那么,只需要把11个数异或之后的结果(N ^ n)再去和1-10异或之后的结果(N)相异或,即 N ^ n ^ N = n
  2. 不使用中间变量的情况下交换两个数
    在交换两个数的问题上,一般只想得到通过一个中间变量,比如:
	int temp = x;
	x = y;
	y=temp

   我们学习了异或之后,就有了新的解题方法!

	x = x ^ y;
	y = x ^ y;
	x = x ^ y;

   第二步我们可以解读成(x ^ y) ^ y = x。同理第三步为(x ^ y) ^ x = y

异或操作是不是超级厉害,咩哈哈哈哈哈!!!!!!!!!!!!

2019.6.13更


待更新···

你可能感兴趣的:(算法中的奇技淫巧)