位运算算法:
例题1:二进制中1的个数
import java.io.*;
class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count=0;
while(n!=0){
++count;
n=(n-1)&n;
}
return count;
}
}
public class 二进制中1的个数 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) {
int n = Integer.parseInt(line);
int ret = new Solution().hammingWeight(n);
String out = String.valueOf(ret);
System.out.print(out);
}
}
}
例题2:只出现一次的数字
异或运算有以下三个性质。
任何数和 0 做异或运算,结果仍然是原来的数
任何数和其自身做异或运算,结果是 0
异或运算满足交换律和结合律,a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b。
class Solution {
public int singleNumber(int[] nums) {
int result=0;
for(int num:nums){
result^=num;
}
return result;
}
}
例题3:有1亿个数字,其中有2个是重复的,快速找到它,时间和空间要最优
public class Test1 {
public static void main(String[] args) {
//1亿长度
int[] arr = new int[100000000];
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
arr[99999999] = 2020;
long st = System.currentTimeMillis();
int min = arr[0];
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
if (arr[i] > max) {
max = arr[i];
}
}
byte[] bucket = new byte[(max - min) / 8 + 1];
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
int j = (num - min) / 8;
int k = (num - min) % 8;
if (((bucket[j] >> k) & 1) > 0) {
//重复了
System.out.println("Number of repeats:" + num);
break;
} else {
bucket[j] |= (1 << k);
}
}
long et = System.currentTimeMillis();
System.out.println("用时:" + (et - st) + "ms");
}
}