算法--位运算

算法原理

常见的位运算总结

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-sum[nums];

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;
    }
}
相关推荐
无极低码2 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发3 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
superior tigre3 小时前
22 括号生成
算法·深度优先
努力也学不会java4 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
旖-旎5 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针
ECT-OS-JiuHuaShan5 小时前
朱梁万有递归元定理,重构《易经》
算法·重构
智者知已应修善业6 小时前
【51单片机独立按键控制数码管移动反向,2片74CH573/74CH273段和位,按键按下保持原状态】2023-3-25
经验分享·笔记·单片机·嵌入式硬件·算法·51单片机
khddvbe6 小时前
C++并发编程中的死锁避免
开发语言·c++·算法
C羊驼6 小时前
C语言:两天打鱼,三天晒网
c语言·经验分享·笔记·算法·青少年编程
菜菜小狗的学习笔记6 小时前
剑指Offer算法题(四)链表
数据结构·算法·链表