1. 只出现一次的数字
// leetcode 136 出现两遍的数都会异或成0,0和一次出现的数异或得到该数
class Solution {
public int singleNumber(int[] nums) {
// Map<Integer,Integer> map = new HashMap<>();
// for(int i=0; i<nums.length; i++){
// Integer value = map.get(nums[i]);
// if(value == null){
// map.put(nums[i],1);
// }else{
// map.put(nums[i],value+1);
// }
// }
// for(int key: map.keySet()){
// if(map.get(key) == 1){
// return key;
// }
// }
// return 0;
int result = 0;
for(int i=0; i<nums.length; i++){
result = result^nums[i];
}
return result;
}
}
// 任何数和0做异或, 结果仍为原来的数,即:a^0 = 0^a = a
// 任何数和其自身做异或,结果为0,即:a^a=0
// 异或运算满足交换率和结合律,即:a^b^a = b^a^a = b^(a^a) = b^0 = b
2. 只出现一次的数字II
// leetcode 137
class Solution { public int singleNumber(int[] nums) { // 3(a+b+c)-(a+a+a+b+b+b+c) = 2c long all_sum = 0; Set<Long> set = new HashSet<Long>(); for(int i=0; i<nums.length; i++){ set.add((long)nums[i]); all_sum += nums[i]; } long element_sum = 0; for(Long value : set){ element_sum += value; } return (int)((3*element_sum-all_sum)/2); }}
3. 只出现一次的数字III
// leetcode 260 注释里面的是方法一
class Solution { public int[] singleNumber(int[] nums) { // Map<Integer,Integer> map = new HashMap<>(); // for(int num:nums){ // int value = map.getOrDefault(num,0)+1; // map.put(num, value); // } // int[] result = new int[2]; // int index = 0; // for(int key:map.keySet()){ // if(map.get(key) == 1){ // result[index] = key; // index++; // } // } // return result; int temp = 0; for(int num:nums){ temp ^= num; } // divide = 1, divide 一直往左移,找到temp第一位不为0的数 int divide = 1; while((divide & temp) ==0){ divide <<= 1; } int a = 0, b=0; for(int num: nums){ if((num & divide) != 0){ a ^= num; }else{ b ^= num; } } return new int[]{a,b}; }}
4. 位1的个数
// leetcode 191
public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { int result = 0; int i = 0; int op = 1; while(i<32){ if((op & n) != 0){ result++; } op <<= 1; i++; } return result; }}
5. 比特位计数
// leetcode 338
class Solution { public int[] countBits(int num) { int[] result = new int[num+1]; for(int i=0; i<=num; i++){ result[i] = oneNum(i); } return result; } private int oneNum(int n){ int result = 0; int i = 0; int op = 1; while(i<32){ if((op & n) != 0){ result++; } op <<= 1; i++; } return result; }}
6. 颠倒二进制位
// leetcode 190public class Solution { // you need treat n as an unsigned value public int reverseBits(int n) { int result = 0; for(int i=0; i<32; i++){ // n 右移i位,然后和1做与运算,解析出该位是0还是1 int t = (n>>i) & 1; if(t==1){ int move_step = 31 - i; // 把刚才解析出来的 1 左移 move_step 位,然后做或运算 int temp = 1 << move_step; result |= temp; } } return result; }}