位运算:(根据英雄哥的算法基础一百讲做的记得到笔记)
必备知识点:
按位与:
1.作为奇数偶数校验:与1与二进制末尾为1,偶数则为0
2.取固定的几位:取几位&上几位1
3.消除末尾几位。&上几位0,前面&1使得前面值不变
4.2的幂判定
(x)&(x-1)==0
典例:
实现一个二进制函数,输出其中1的个数
代码实现:
int hammingWeight(uint32_t n) {
int c = 0;
while(n) {
n &= (n - 1); // (1)
++c; // (2)
}
return c;
}
异或
1.两个相同的十进制数异或的结果一定为零。
2.任何一个数和 0 的异或结果一定是它本身。
3.异或运算满足结合律和交换律。
题目描述:
给定一个正整数
n
,找到并返回n
的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1,返回0
。如果只有
0
将两个1
分隔开(可能不存在0
),则认为这两个 1 彼此 相邻 。两个1
之间的距离是它们的二进制表示中位置的绝对差。例如,"1001"
中的两个1
的距离为 3 。
我的题解:
#define MAX(a,b) ((a)>(b)?(a):(b))
int binaryGap(int n){
int fir=-1;
int count=0;
for(int i=0;n;++i){
//直到0的时候退出循环
//末尾与1结果为1
if(n&1){
if(fir!=-1){
//更新长度
count=MAX(count,i-fir);
}
fir=i;//记录起始位置
}
//结束之后向右移继续找1的位置
n=n>>1;
}
return count;
}
我的思路:
1.找出每个1的位置然后记录
2.更新长度
题目描述:
给你一个整数数组
perm
,它是前n
个正整数的排列,且n
是个 奇数 。它被加密成另一个长度为
n - 1
的整数数组encoded
,满足encoded[i] = perm[i] XOR perm[i +
1]
。比方说,如果perm = [1,3,2]
,那么encoded = [2,1]
。给你
encoded
数组,请你返回原始数组perm
。题目保证答案存在且唯一。
我的题解:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* decode(int* encoded, int encodedSize, int* returnSize){
int* perm=(int*)malloc(sizeof(int)*(encodedSize+1));
*returnSize=encodedSize+1;
//先把前面n个正整数异或
int n=encodedSize+1;
int total=0;
for(int i=1;i<=n;++i){
total^=i;
}
//这时候把除了第一个数其他的数的异或和求出来在和total亦或可以的出第一个perm的值
//应该是偶数个异或,又有encoded是由perm两两异或出来的也就说encoded有n-1/2的元素
//可以轻易推出从第2个开始两两异或就是隔一个异或就是两个不一样的数异或的值
int total2=0;
for(int i=1;i<n-1;i+=2){
total2^=encoded[i];
}
//得出perm【0】
perm[0]=total^total2;
//后面就很好求了
//根据推导公式
/*
encoded[0] = perm[0] ^ perm[1]
encoded[1] = perm[1] ^ perm[2]
encoded[2] = perm[2] ^ perm[3]
左右异或perm【i】
perm【1】=encoded【0】^perm[0]
*/
for(int i=0;i<n-1;++i){
perm[i+1]=perm[i]^encoded[i];
}
return perm;
}
我的思路:
具体看注释。感觉写的很清楚了