public class E56NumbersAppearOnce {
//数组中数字出现的次数
/*问题一:两个只出现一次的数字+出现两次的其它数字*/
public static void findNumbers(int[] numbers, int length) {
if (numbers == null || length <= 1)
return;
//保存所有数字的异或运算结果
int orResult = 0;
for (int i = 0; i < length; i++) {
orResult ^= numbers[i];
}
//异或结果从右至左第一个1的位置
int moveSteps = getPositionBitIs1(orResult);
int number1 = 0;
int number2 = 0;
for (int i = 0; i < length; i++) {
if (bitIs1(numbers[i], moveSteps))
number1 ^= numbers[i];
else
number2 ^= numbers[i];
}
System.out.printf("只出现一次的两个数字分别为:%d,%d。", number1, number2);
}
private static int getPositionBitIs1(int orResult) {
//返回右移次数
int moveSteps = 0;
while ((orResult & 1) == 0 && moveSteps < 32) {
orResult = orResult >> 1;
moveSteps++;
}
return moveSteps;
}
private static boolean bitIs1(int number, int moveSteps) {
for (int i = 0; i < moveSteps; i++)
number = number >> 1;
return (number & 1) == 1;
}
/*问题二:只出现一次的一个数字+出现三次的其它数字*/
public static int findNumber(int[] numbers, int length) {
if (numbers == null || length <= 0)
throw new IllegalArgumentException("Invalid Input!");
int[] bits = new int[32];
int bitMark = 1;
for (int i = 31; i >= 0; i--) {
for (int j = 0; j < length; j++){
if ((numbers[j] & bitMark) != 0)
bits[i] += 1;
}
bitMark = bitMark << 1;
}
int targetNumber = 0;
for (int i = 0; i < 32; i++){
targetNumber = targetNumber << 1;
targetNumber += (bits[i] % 3);
}
return targetNumber;
}
//测试用例z
public static void main(String[] args) {
int[] numbers1 = {1, 1, 2, 2, 3, 4, 5, 5};
E56NumbersAppearOnce.findNumbers(numbers1, 8);
int[] numbers2 = {1, 1, 1, 2, 2, 2, 3, 4, 4, 4};
System.out.println("\n" + E56NumbersAppearOnce.findNumber(numbers2, 10));
}
}
数组中数字出现的次数(Java实现)
最新推荐文章于 2022-07-08 21:59:48 发布