137. 只出现一次的数字 II
class Solution {public int singleNumber(int[] nums) {int once=0,twice=0;for(int num:nums){once=(once^num)&~twice;twice=(twice^num)&~once;}return once;}}
260. 只出现一次的数字 III
只有两个数字a、b出现了一次,其他数字都出现了两次。全部数字异或的结果就等于a^b。
假设a异或b的结果xor,最右第五位1。
说明a、b的第五位一个是0一个是1,把数组中最右第五位是0的数全部异或一遍,就可以找到那个单独的第五位是0的数字。
同样,把数组中最右第五位是1的数全部异或一遍,就可以找到那个单独的第五位是1的数字。
class Solution {public int[] singleNumber(int[] nums) {int xor=0;for(int num:nums){xor=xor^num;}int flag=1;while((xor&1)==0){xor=xor>>1;flag=flag<<1;}int a=0,b=0;for(int num:nums){if((flag&num)==0){a=a^num;}else{b=b^num;}}return new int[]{a,b};}}
89. 格雷编码
class Solution {public List<Integer> grayCode(int n) {/**关键是搞清楚格雷编码的生成过程, G(i) = i ^ (i/2);如 n = 3:G(0) = 000,G(1) = 1 ^ 0 = 001 ^ 000 = 001G(2) = 2 ^ 1 = 010 ^ 001 = 011G(3) = 3 ^ 1 = 011 ^ 001 = 010G(4) = 4 ^ 2 = 100 ^ 010 = 110G(5) = 5 ^ 2 = 101 ^ 010 = 111G(6) = 6 ^ 3 = 110 ^ 011 = 101G(7) = 7 ^ 3 = 111 ^ 011 = 100**/List<Integer> res = new ArrayList<>();for(int i=0;i<(1<<n);i++){res.add(i^(i>>1));}return res;}}
也可以用dfs,但是应该不是题目的本意?
因为这样才打败了10%
class Solution {List<Integer> res = new ArrayList();boolean[] visited;public List<Integer> grayCode(int n) {visited = new boolean[1<<n];dfs(0,n);return res;}void dfs(int cur,int n){if(res.size()==(1<<n))return;res.add(cur);visited[cur]=true;for(int i=0;i<n;i++){int next = cur^(1<<i); //这里改变cur的某一位,用异或if(!visited[next]) dfs(next,n);}}}
338. 比特位计数
要多写几位找规律。
比如:
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
16 10000
如果i是奇数,就只比上一个数多了一个末尾的1
如果i是偶数,就是把(从右往左数)1-n位的连续1变成n+1位的1
class Solution {public int[] countBits(int num) {int[] dp=new int[num+1];if(num==0) return dp;for(int i=1;i<=num;i++){if(((i-1)&1)==0){dp[i]=dp[i-1]+1;}else{dp[i]=dp[i-1]-countOne(i-1)+1;}}return dp;}private int countOne(int n){int count=0;while((n&1)==1){n=n>>1;count++;}return count;}}
