【算法】给定一个数组,除了一个数出现1次之外,其余数都出现3次,输出出现一次的那个数。
2016-09-23 13:44
405 查看
给定一个数组,除了一个数出现1次之外,其余数都出现3次。找出出现一次的数。如:{1, 2, 1, 2, 1, 2, 7},找出7.格式:第一行输入一个数n,代表数组的长度,接下来一行输入数组A
,(输入的数组必须满足问题描述的要求),最后输出只出现一次的数。
上面这种方法绝大多数人肯定都会,但是我觉得算法效率肯定很低。来想想另外一种方法。
首先看看题目要求:
数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次。请给出最快的方法找到x。应该如何思考呢?
如果是两个相同的就可以利用两个相同的数异或结果为0来计算的,但这个题目中其他数字是出现了3次,因此肯定不可以再使用异或了。
我们换一个角度来看,如果数组中没有x,那么数组中所有的数字都出现了3次,在二进制上,每位上1的个数肯定也能被3整除。如{1, 5, 1, 5, 1, 5}从二进制上看有:
1:0001
5:0101
1:0001
5:0101
1:0001
5:0101
二进制第0位上有6个1,第2位上有3个1.第1位和第3位上都是0个1,每一位上的统计结果都可以被3整除。而再对该数组添加任何一个数,如果这个数在二进制的某位上为1都将导致该位上1的个数不能被3整除。因此通过统计二进制上每位1的个数就可以推断出x在该位置上是0还是1了,这样就能计算出x了。
推广一下,所有其他数字出现N(N>=2)次,而一个数字出现1次都可以用这种解法来推导出这个出现1次的数字。
例子程序:
下载源码请上我的GitHub
,(输入的数组必须满足问题描述的要求),最后输出只出现一次的数。
package yn; import java.util.Scanner; public class OutputMin { public static void main(String[] args) { Scanner input = new Scanner(System.in); int i = 0; int j = 0; int k = 0; int n = input.nextInt(); int a[] = new int ; Scanner in = new Scanner(System.in); System.out.println("请输入一个数组"); for (i = 0; i < n; i++) { a[i] = in.nextInt(); System.out.print(a[i] + " "); } System.out.println(); for (j = 0; j < n; j++) { int f = 0; for (k = 0; k < n; k++) { if (a[j] == a[k]) { f++; } } if (f == 1) { System.out.println(a[j]); break; } } } }
上面这种方法绝大多数人肯定都会,但是我觉得算法效率肯定很低。来想想另外一种方法。
首先看看题目要求:
数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次。请给出最快的方法找到x。应该如何思考呢?
如果是两个相同的就可以利用两个相同的数异或结果为0来计算的,但这个题目中其他数字是出现了3次,因此肯定不可以再使用异或了。
我们换一个角度来看,如果数组中没有x,那么数组中所有的数字都出现了3次,在二进制上,每位上1的个数肯定也能被3整除。如{1, 5, 1, 5, 1, 5}从二进制上看有:
1:0001
5:0101
1:0001
5:0101
1:0001
5:0101
二进制第0位上有6个1,第2位上有3个1.第1位和第3位上都是0个1,每一位上的统计结果都可以被3整除。而再对该数组添加任何一个数,如果这个数在二进制的某位上为1都将导致该位上1的个数不能被3整除。因此通过统计二进制上每位1的个数就可以推断出x在该位置上是0还是1了,这样就能计算出x了。
推广一下,所有其他数字出现N(N>=2)次,而一个数字出现1次都可以用这种解法来推导出这个出现1次的数字。
例子程序:
package yn; import java.util.Arrays; public class OutputMinJava { public static void main(String[] args) { int a[] = { 2, 3, 1, 2, 3, 4, 1, 2, 3, 1, 4, 4, 5 }; for (int j = 0; j < a.length; j++) { System.out.print(a[j]); } System.out.println(); System.out.println(findNumber(a, a.length)); } public static int findNumber(int a[], int n) { int bits[] = new int[32]; Arrays.fill(bits, 0); int i, j; for (i = 0; i < n; i++) for (j = 0; j < 32; j++) bits[j] += ((a[i] >> j) & 1); // 如果某位上的结果不能被整除,则肯定目标数字在这一位上为 int result = 0; for (j = 0; j < 32; j++) if (bits[j] % 3 != 0) result += (1 << j); return result; } }
下载源码请上我的GitHub
相关文章推荐
- 一个java数学题,给定一个数组,除了一个数出现1次之外,其余数都出现3次,输出出现一次的那个数。
- 算法题:从数组找数字(网易2017校园招聘) 2017-10-10 算法爱好者 (点击上方公众号,可快速关注) 给定一个数组,除了一个数出现 1 次之外,其余数都出现 3 次。找出出现一次的数。
- 给定整数数组,除了一个元素之外,每个元素都出现三次。 找到那个只出现一次的数
- 给定整数数组,除了一个元素之外,每个元素都会出现两次。 找到那个只出现一次的
- Java__给定一个数组 AA,除了一个数出现一次之外,其余数都出现三次。找出出现一次的数。
- 给定一个数组 AA,除了一个数出现一次之外,其余数都出现三次。找出出现一次的数。
- 一个数组中除了两个数字之外,其余数字均出现了两次,如{1,2,3,4,5,3,2,1}.查找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
- 有一个排好序的数列,数列中只有一个数只出现1次,其余每个数均出现了两次,设计出一个算法,找出那个只出现了一次的数
- 算法习题61:找出数组中两个只出现一次的数字:一个整型数组里除了两个数字之外,其他的数字都出现了两次
- 一个全是32位整数的大数组,除了其中一个数字出现2次外,其余的数字都出现了3次。如何找出那个只出现了两次的数字?
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次,请写程序找出这两个出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次,请写程序找出这两个只出现一次的数字
- 数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次。请给出最快的方法,找到x
- 在一个长度为n的整形数组a里,除了三个数字只出现一次外,其他的数字都出现了2次。请写程序输出任意一个只出现一次的数字
- 一个整型数组里除了一个数字之外,其他的数字都出现了两次,找出出现一次的数字
- 一个数组中除了两个数字之外,其余数字都出现了两次,找出这两个数字
- 一个数组中除了三个数字之外,其余数字都出现了两次,找出这三个数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次