算法--位运算

算法原理

常见的位运算总结

1.基础位运算

<<左移

>>右移

~按位取反

&按位与 有0就是0

|按位或 有1就是1

^异或 相同位0,相异为1/无进位相加

2.给定一个数n,确定他的二进制表示中的第x位是0还是1

3.将一个数n的二进制位表示的第x位修改为1

4.将一个数n的二进制位表示的第x位修改为0

5.位图的思想(本质就是哈希表)

我们可以用int\[\]来模拟一个哈希表,但当数据过大的时候,这样并不适用,我们就尝试使用位图的思想,一个int有32个比特位,每个位置可以存储0或1的信息,这样能存储的数据就大幅度增加了

(上述2,3,4都是应用了位图的思想)

6.提取一个数(n)二进制表示中最右侧的1

n&-n

7.干掉一个数(n)二进制表示中最右侧的1

n&n-1

8.运算符的优先级

能加括号就加括号

9.异或运算的运算律

1.a^0=a;

2.a^a=0;

3.a^b^c=a(b^c)

题目解析

1.判断字符是否唯一

https://leetcode.cn/problems/is-unique-lcci/

题目描述

实现一个算法,确定一个字符串s的所有字符是否全部不同

算法原理

解法一:哈希表(o(n)的时间复杂度和空间复杂度)

解法二:位图

优化点:鸽巢原理(如果len>26,一定有重复的字符出现)

代码实现

复制代码
public boolean isUnique(String astr) {
        if(astr.length()>26){
            return false;
        }
        int bitMap=0;
        for(int i=0;i<astr.length();i++){
            int x=astr.charAt(i)-'a';
            if(((bitMap>>x)&1)==1) return false;
            bitMap |=1<<x;
        }
        return true;
    }

2.消失的数

https://leetcode.cn/problems/missing-number/description/

题目描述

给定一个包含0,n中n个数的数组nums,找出0,n这个范围内没有出现在数组中的那个数

算法原理

1.哈希表

将数组中的元素加到哈希表中,然后遍历哈希表找出那个不存在的元素(用数组模拟实现哈希表,遍历数组,存在将数组对应的值改为1)

2.高斯求和

ret=(0+nums.length)/2-sumnums;

3.位运算(异或运算的运算律)

a^a=0 a^0=a;

让0与数组中每一位异或,再与0异或到数组的 长度,这样出现的数被异或了2次,结果不受影响,而未出现的数字被异或了一次,结果就会是缺失的数字

代码实现

复制代码
    public int missingNumber(int[] nums) {
        int ret=0;
        for(int num:nums){
            ret^=num;
        }
        for(int i=0;i<=nums.length;i++){
            ret^=i;
        }
        return ret;
    }

3.两整数之和

https://leetcode.cn/problems/sum-of-two-integers/

题目描述

给你两个整数a和b,不使用运算符+和-,计算并返回两整数之和

算法原理

位运算(异或运算--无进位相加)

代码实现

复制代码
class Solution {
    public int getSum(int a, int b) {
        while(b!=0){
            int x=a^b;
            b=(a&b)<<1;
            a=x;
        }
        return a;
    }
}

4.只出现一次的数字

https://leetcode.cn/problems/single-number-ii/

题目描述

给定一个数组nums,除某个元素仅出现一次外,其余元素恰好出现了三次,请找出并返回哪个只出现了一次的元素

算法原理

使用位图的思想,依次修改ret每个比特位的值,每次修改的时候统计所有数字第i位的和,如果最后结果%3的结果为1,ret|=(1<<i)

代码实现

复制代码
class Solution {
    public int singleNumber(int[] nums) {
        int ret=0;
        for(int i=0;i<32;i++){
            int sum=0;
            for(int x:nums){
                if(((x>>i)&1)==1){
                    sum++;
                }
            }
            sum=sum%3;
            if(sum==1){
                ret|=(1<<i);
            }
        }
        return ret;
    }
}

5.消失的两个数

https://leetcode.cn/problems/missing-two-lcci/

题目描述

给定一个数组,包含从1到n的所有整数,但是缺少了两个数字,在O(N)时间内在O(1)空间里找到这两个数字

算法原理

这道题类似于丢失的数字+只出现一次的数字

解法:位运算

1.将所有的数异或在一起,tmp

2.找到tmp中比特位为1的那一位

3.根据x位的不同,划分两类进行异或

代码实现

java 复制代码
class Solution {
    public int[] missingTwo(int[] nums) {
        // 1.先把所有的数字异或在一起
        int tmp=0;
        for(int x:nums){
            tmp^=x;
        }
        for(int i=1;i<=nums.length+2;i++){
            tmp^=i;
        }
        // 2.找出a b比特位不同的哪一位
        int diff=0;
        while(true){
            if(((tmp>>diff)&1)==1){
                break;
            }else{
                diff++;
            }
        }
        // 3.将所有的数按照diff位不同,分成两类异或
        int[] ret=new int[2];
        for(int x:nums){
            if(((x>>diff)&1)==1) ret[1]^=x;
            else{
                ret[0]^=x;
            }
        }
        for(int i=1;i<=nums.length+2;i++){
            if(((i>>diff)&1)==1)
            ret[1]^=i;
            else{
                ret[0]^=i;
            }
        }
        return ret;
    }
}
相关推荐
青少儿编程课堂1 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会图形化考级:校园大富翁经营闯关解析
c++·python·算法·bfs·信息学竞赛
在所不辞兄2 小时前
为什么在新能源汽车电驱与热管理开发中,AI驱动的数字孪生和数据驱动仿真正在部分替代对物理台架与实车标定的依赖?
人工智能·深度学习·神经网络·算法·机器学习
I_belong_to_jesus12 小时前
C++关于分支预测的优化1
开发语言·c++·算法
Code_Solitude19 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司19 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP1 天前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀1 天前
背包DP(01背包+完全背包)
c++·算法
笑容掩饰我的失落1 天前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法
Pniubi1 天前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表