清除最右边的‘1’ n & ( n − 1 ) n\&(n-1) n&(n−1)
给定一个整数,计算其二进制表示中‘1’的个数
int popCount(uint64 n){
int c = 0;
while(n){
n &= (n-1);
c++;
}
}
- n & ( n − 1 ) n\&(n-1) n&(n−1) 操作能清除n的最右边的’1’
判断一个数是否是2的幂
int isPower(uint64 n){
return n&(n-1) == 0;
}
- 2的幂次方的数,其二进制表示中,只有一个1,故只要判断n的二进制表示中是否只有一个‘1’即可。
获取最右边的’1’ n & ( − n ) n\&(-n) n&(−n)
a = n & ( − n ) a = n\&(-n) a=n&(−n),可以获取到最右边的‘1’,例如: n = 10 = 0b 01010, -n = 0b10110,a = 0b00010
XOR 操作
数组中的数只有一个出现odd次,其他都是even次,找出出现一次的数
int findOdd(vector<int>& nums){
int res = 0;
for(int i = 0; i < nums.size(); ++i){
res ^= nums[i];
}
return res;
}
计算 从1到n的xor值
Number Binary-Repr XOR-from-1-to-n
1 1 [0001]
2 10 [0011]
3 11 [0000] <----- We get a 0
4 100 [0100] <----- Equals to n
5 101 [0001]
6 110 [0111]
7 111 [0000] <----- We get 0
8 1000 [1000] <----- Equals to n
9 1001 [0001]
10 1010 [1011]
11 1011 [0000] <------ We get 0
12 1100 [1100] <------ Equals to n
long computeXOR(int n){
switch(n&3){
case 0: return n;
case 1: return 1;
case 2: return n+1;
case 3: return 0;
}
}
查找缺失的数字
- 给定n-1大小的数组,存放的数字范围:[1,n],且没有重复的,找到缺失的数字
- a = a0 ^ a1 ^ a2 ^ … ^ an,b = a0 ^ a1 ^ a2 ^ … ^ an-1;
- a^b = an
int getMissingNo(vector<int> & nums){
int x1 = nums[0];
int x2 = 1;
for(int i = 1; i < nums.size(); ++i){
x1 ^= nums[i];
}
for(int i = 2; i <= nums.size() + 1; ++i){
x2 ^= i;
}
return x1^x2
}
给定范围,查找缺失的数字
- 给定一个数组 array,其最小值称为 smallest,数组长度为n,则 i ∈ [ s m a l l e s t , s m a l l e s t + n ] , w h e n i ∈ a r r a y , i\in[smallest,smallest+n],when i\in array, i∈[smallest,smallest+n],wheni∈array,,其中每个数字都不相同
int getMissingNo(vector<int>& nums){
int smallest = *std::min_element(nums.begin(),nums.end());
int x1 = nums[0];
int x2 =smallest;
for(int i = 1;i < nums.size();++i){
x1 ^= nums[i];
}
for(int i = 1; i <= nums.zie(); ++i){
x2 ^= i+smallest;
}
return x1 ^ x2;
}
给定排序数组,每个数字都不相同,且每个数字的范围是[0,m-1],m>n,找到数组中最小的确实数字
- 剑指offer53-11 0~n-1 中缺失的数字
Examples
Input: {0, 1, 2, 6, 9}, n = 5, m = 10
Output: 3
Input: {4, 5, 10, 11}, n = 4, m = 12
Output: 0
Input: {0, 1, 2, 3}, n = 4, m = 5
Output: 4
Input: {0, 1, 2, 3, 4, 5, 6, 7, 10}, n = 9, m = 11
Output: 8
线性查找
int findSmallestMissingNo(std::vector<int>& nums,int l,int r,int c,int m){
if(l > r || nums[l] != c){
return c;
}
return findSmallestMissingNo(nums,l+1,r,c+1,m);
}
二分查找
- 对 0n-1进行二分查找,认为数组中的元素和0n 对应,
int findSmallestMissingNo(vector<int>& nums,int l,int r){
if(l > r) return r+1;
if(l != nums[l]) return l;
int mid = (l+r)/2;
if(mid == nums[mid])
return findSmallestMissingNo(nums,mid+1,r);
else
return findSmallestMissingNo(nums,l,mid);
}