目录
🌿位运算前置知识
🧊1.基础位运算
🍋🟩单目运算符
<<左移操作符
左移操作符,我的理解是比特位左移(对于负数,这个操作会不管符号位,都会左移),右边统统补0,不保持正负数的不变
>>右移操作符右移操作符,我的理解是比特位右移,左边统统补符号位,补符号位的作用是,保持正负数的不变
~按位取反操作符
~按位取反操作符,所有的比特位(包括符号位)都取反!这点要和右移操作符>>区分开,不保持正负数的不变
其实吧,就右移操作符>>特殊,其它的只要记住按照字面逻辑来,不管啥符号位啥不是符号位的,一视同仁
后面我会专门举例讲解这块知识的,我始终觉得只有真正实践了,才是真家伙,其它虚的也有重要的,但3分靠听课,7分靠实践,干就完了,加油,兄弟们
🍋🟩双目运算符
按位与&
比特位上,有0就为0
按位或|比特位上,有1就为1
按位异或^比特位上,相同为0,相异为1,关于这个操作符,还有一种叫法叫"无进位相加"
具体的为啥叫无进位相加,自己理解,惯的!!
🧊2.给一个数n,确定它的二进制表示中的第x位是0还是1
这里确定的是补码的比特位的,正数原反补都一样,负数就只能确定补码,其它的不行
操作:(n>>x)&1,看这个(n>>x)&1结果是0就代表数n的第x位是0,结果是1就代表数n的第x位是1
论证

🧊3.将一个数n的二进制表示的第x位修改成1
操作:n |= (1<<x) 或者是 n = n| (1<<x)
论证

🧊4.将一个数n的二进制表示的第x位修改成0
操作 : n &= (~(1<<x))或者是n = n & (~(1<<x))
论证

🧊5.提取一个数(n)二进制表示中最右侧的1
操作 n & -n
论证



🧊6.干掉一个数(n)二进制表示中最右侧的1
操作 : n & (n-1)
论证

前置知识需要细品,有的时候,慢就是快,学习算法需要长时间的不断积累,厚积薄发,各位道友!
🌿判断字符是否唯一
🧊题目链接
https://leetcode.cn/problems/is-unique-lcci/description/
🧊题目描述

🧊解题思路


🧊解题代码
java
class Solution {
public boolean isUnique(String astr) {
int flag_ret=0;//相当于一个数组,存着不同字符的是否唯一的信息
if(astr.length()>26){//超过26个字符,就一定是有某个字符存在2个或2个以上
return false;
}
for(int i=0;i<astr.length();i++){//要熟悉好charAt()方法,注意大小写,
int n=astr.charAt(i)-'a';//相当于是确定当前字符所对应的下标
if(((flag_ret>>n)&1)==1){//给一个数n,确定它的二进制表示中的第x位是0还是1,操作(n>>x)&1
return false;这个是已经存在了,当前字符是第二个字符,所以直接返回false
}else{//将一个数n的二进制表示的第x位修改成1 ,操作:n |= (1<<x)
flag_ret |=(1<<n);//这里当然是维护flag_ret了
}
}
return true;//跑到最后,就是最后的强者
}
}
🌿丢失的数字
🧊题目链接
https://leetcode.cn/problems/missing-number/description/
🧊题目描述

这个题比较简单啊哈哈,就涉及一个点^的运算逻辑,a^0=a ,a^a=0 ,0^0=0,就不写解题思路了哈
🧊解题代码
java
class Solution {
public int missingNumber(int[] nums) {
int n=0;
for(int i=0;i<nums.length+1;i++){//原数组+1长度
n^=i;
}
for(int j=0;j<nums.length;j++){//原数组长度
n^=nums[j];
}
return n;
//二分解法,撞了哈哈哈,有点惊喜
// Arrays.sort(nums);
// int left=0,right=nums.length-1;//这个还是得结合画图来,有时候光靠脑子想,难呢
// while(left<right){
// int mid=left+(right-left)/2;
// if(nums[mid]==mid){//注意拿啥判断
// left=mid+1;
// }else{
// right=mid;
// }
// }
// return nums[left]==left?left+1:left;//不能漏掉第二种情况
}
}
🌿两整数之和
🧊题目链接
https://leetcode.cn/problems/sum-of-two-integers/
🧊题目描述

🧊解题思路


按照这个逻辑,然后我们运用循环,直到b为0就退出循环

🧊解题代码
java
class Solution {
public int getSum(int a, int b) {
while(b!=0){
int x=a^b;//无进位相加
int last_ret=(a&b)<<1;//计算进位
a=x;//这个就是迭代结果
b=last_ret;//当这个b为0时就是不需要进位
}
return a;返回进位迭代结果即可
}
}
🌿只出现一次的数字||
🧊题目链接
https://leetcode.cn/problems/single-number-ii/
🧊题目描述

🧊解题思路


哎,感觉脑力要被榨干了,不过还好,打发时间感觉还行
🧊解题代码
java
class Solution {
public int singleNumber(int[] nums) {
int ret=0;//这个比特位全是0,所以只要修改1就行,默认0
for(int i=0;i<32;i++){
int sum=0;//每次计算不同的比特位时重置
for(int j=0;j<nums.length;j++){//数组里的数的第i个比特位相加逻辑
if(((nums[j]>>i)&1)==1){//碰到比特位是1就sum++
sum++;
}
}
sum%=3;//发挥奇迹,能正确确认落单数值二进制第i个比特位的1还是0
if(sum==1){//是1就修改,记住0是默认的
ret|=(1<<i);
}
}
return ret;//返回修改过后的落单数值
}
}
🌿消失的两个数字
🧊题目链接
https://leetcode.cn/problems/missing-two-lcci/description/
🧊题目描述

🧊解题思路
此题解法我觉得特别巧妙,用到了,只用到了位运算的判断操作(n>>x)&1

🧊解题代码
java
class Solution {
public int[] missingTwo(int[] nums) {
int ret=0;
for(int i=0;i<nums.length;i++){//ret异或原数组
ret^=nums[i];
}
for(int i=1;i<=nums.length+2;i++){//ret异或原数组+2长度
ret^=i;
}
int flag_bite=0;//^的特性,不同为1,去找一即可,其它不是a和b的数都抵消了
while(true){
if(((ret>>flag_bite)&1)==1){//找到不同的那个比特位了,break出循环
break;
}else{
flag_bite++;//继续遍历
}
}
int[] arr=new int[2];//用来存储a和b的数值信息
for(int i=0;i<nums.length;i++){//原数组的操作
if(((nums[i]>>flag_bite)&1)==1){//原数组的划分
arr[0]^=nums[i];
}else{
arr[1]^=nums[i];
}
}
for(int i=1;i<=nums.length+2;i++){//原数组+2的操作
if(((i>>flag_bite)&1)==1){//原数组+2的划分
arr[0]^=i;
}else{
arr[1]^=i;
}
}
return arr;
}
}
🧊🧊完结!!