版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
问题描述:一个整型数组里除了一个数字之外,其他数字都出现了2次。找出这个只出现1次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
方法:由于时间复杂度与空间复杂度的限制,题目强调只有一个数字出现了1次,其余数字出现了2次。可以通过异或运算,因为任何一个数字异或它自己都等于0,所以从头到尾依次异或数组中的每一个数字。出现两次的数字会在异或中被抵消掉,最终的结果就是只出现1次的数字。
注意:该方法具有局限性,异或运算只能适用于数字出现次数为偶数的情况,如果出现次数为奇数,则不适用。
代码如下:
package com.haobi;
/*
* 如何找出数组中只出现一次的数字?
*/
public class Test14 {
public static void main(String[] args) {
int[] array = {1,2,3,2,4,3,5,4,1,5};
int num = findNotDouble(array);
System.out.println(num);
}
public static int findNotDouble(int[] a) {
int result = 0;
for(int aa : a) {
result ^= aa;
}
return result;
}
}
引申:如果在数组中,一个整型数组里除了一个数字之外,其他数字都出现了3次,那么如何找出这个数?
方法:如果数组中的所有数都出现了n次,那么这个数组中的所有数对应的二进制数中,各个位上的1出现的个数可以被n整除。
代码如下:
package com.haobi;
/*
* 如何找出数组中只出现一次的数字?(其他数字都出现了3次)
*/
public class Test15 {
public static void main(String[] args) {
int[] array = {1,2,1,2,4,2,4,4,1,3};
int num = findOnce(array,3);
System.out.println(num);
}
public static int findOnce(int[] a, int appearTimes) {
int n = a.length;
int[] bitCount = new int[32];
//计算数组中所有数组对应的二进制数各个位置上出现1的次数
for(int i=0;i<n;i++) {
for(int j=0;j<32;j++) {
bitCount[j] += ((a[i] >> j)&1);
}
}
//若某位上的结果不能被整除,则肯定目标数字在这一位上
int appearOne = 0;
for(int i=0;i<32;i++) {
if(bitCount[i] % appearTimes != 0) {
appearOne += (1<<i);
}
}
return appearOne;
}
}