int[] getOddTimesNumbers(int[] array) { int xor = 0; for (int i: array) { xor ^= i; }
// xor == a ^ b // 因为 a != b (两种数),所以 a ^ b != 0,则必然存在为 1 的二进制位 // 不妨就使用最后一个 1,即 int one = xor & (~xor + 1); // 假设这个 1 在第 N 位 int a = 0; for (int i: array) { // 将数组分为两类:1. N 位上为 1 的;2. N 位上为 0 的。 // a 和 b 一定分别属于这两类,不会同属一类,因为 a ^ b 的 N 位是 1 // 这里只把第 1 类异或起来,得到一种数 if ((i & one) != 0) { a ^= i; } }
// 用之前得到的这种数异或 xor,得到另一种 returnnewint[]{a, a ^ xor}; }
Java 实现(函数式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
int[] getOddTimesNumbers(int[] array) { int xor = Arrays.stream(array).reduce(0, (a, b) -> a ^ b);
int one = xor & (~xor + 1); int a = Arrays.stream(array).reduce(0, (v1, v2) -> { if ((v2 & one) != 0) { return v1 ^ v2; } else { return v1; } });
returnnewint[] {a, xor ^ a}; }
Rust 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
fnget_odd_times_numbers(array: &[i32]) -> (i32, i32) { letmut xor = 0; for i in array { xor ^= *i; }
let one = xor & (!xor + 1); letmut a = 0; for i in array { if one & *i != 0 { a ^= *i; } }
(a, xor ^ a) }
Rust 实现(函数式)
1 2 3 4 5 6 7 8 9 10 11
fnget_odd_times_numbers(array: &[i32]) -> (i32, i32) { let xor = array.iter().fold(0, |a, b| a ^ *b);
let one = xor & (!xor + 1); let a = array .iter() .fold(0, |a, b| if one & b != 0 { a ^ *b } else { a });
#[test] fntest_get_odd_times_numbers() { use rand::prelude::*;
letmut rng = thread_rng();
for _ in0..1000 { letmut vec = Vec::new(); let odd_number_a = rng.gen_range(0..5); let odd_number_b = loop { let b = rng.gen_range(0..5); if b != odd_number_a { break b; } else { continue; } }; for i in0..5 { let times: usize = rng.gen_range(1..3) * 2 + if i == odd_number_a || i == odd_number_b { 1 } else { 0 }; for _ in0..times { vec.push(i); } } vec.shuffle(&mut rng);
let get = get_odd_times_numbers(&vec); assert!(get == (odd_number_a, odd_number_b) || get == (odd_number_b, odd_number_a)); } }
5. 计算某个数为 1 的二进制位数
例如:
1
0b00101100 --> 3
Java 实现
1 2 3 4 5 6 7 8 9 10 11 12
intcountOnes(int a){ int count = 0;
while (a != 0) { count += 1; int one = a & (~a + 1); a ^= one; // 把这个 1 给去掉 }