【算法通关】位运算:位图、异或消消乐,高频算法题全解

文章目录

    • [1. 判定字符是否唯一](#1. 判定字符是否唯一)
    • [2. 丢失的数字](#2. 丢失的数字)
    • [3. 两整数之和](#3. 两整数之和)
    • [4. 只出现一次的数字 ||](#4. 只出现一次的数字 ||)
    • [5. 消失的两个数](#5. 消失的两个数)

1. 判定字符是否唯一

题目链接:判定字符是否唯一

题目描述:

算法思路:位运算,位图

当字符串长度大于26时,那么一定存在重复字符,直接返回即可。

利用位图,每一个比特位代表一个字符,一个int类型的变量足够表示所有的小写字母,比特位是0 表示这个字符没有出现过,比特位里面的值是1 表示该字符出现过。

算法代码:

java 复制代码
	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. 丢失的数字

题目链接:268. 丢失的数字

题目描述:

算法思路:位运算

异或的运算律,a ^ a = 0,因此可以使用异或^消消乐,先将nums数组里的数全部异或在一起,然后将 0 , n 区间内的数也异或在一起,那么得到的就是只出现一次的数。

算法代码:

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

3. 两整数之和

题目链接:371. 两整数之和

题目描述:

算法思路:位运算

异或操作是无进位相加,那么a & b 找到进位,并且左移 1 位,当进位为0 时,异或的结果就是两数之和。

算法代码:

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

4. 只出现一次的数字 ||

题目链接:137. 只出现一次的数字 ||

题目描述:

算法思路:位运算

在整个数组中,有一个数出现一次,其余都出现三次,那么将每一个比特位相加并 % 3,那么得出的就是单次出现元素对应的比特位,将32位都这样求出来就可以还原这个数。

算法代码:

java 复制代码
	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 %= 3;
            if(sum == 1) ret |= (1 << i);
        }
        return ret;
    }

5. 消失的两个数

题目链接:消失的两个数

题目描述:

算法思路:

将数组和1到n的数全部异或在一起,可以得到缺失两个数的异或。可以根据异或比特位为1的位置将数组分成两部分,一部分为该比特位为0,一部分该比特位为1。然后分别将两个数组的两部分异或在一起,就分别得到了缺失的数。

算法代码:

java 复制代码
	public int[] missingTwo(int[] nums) {
        int tmp = 0;
        for(int i = 0; i < nums.length; i++){
            tmp ^= nums[i];
        }
        for(int i = 0; i <= nums.length+2; i++){
            tmp ^= i;
        }

        int diff = 0;
        while(true){
            if(((tmp >> diff) & 1) == 1) break;
            else diff++;
        }
        int ret[] = new int[2];
        for(int x : nums){
            if(((x >> diff) & 1) == 1) ret[0] ^= x;
            else ret[1] ^= x;
        }
        for(int i = 0; i <= nums.length+2; i++){
            if(((i >> diff) & 1) == 1) ret[0] ^= i;
            else ret[1] ^= i;
        }
        return ret;
    }
相关推荐
wabs66610 小时前
关于图论【卡码网117.软件构建的思考】
数据结构·算法·软件构建·图论·卡码网
mifengxing11 小时前
LeetCode 41.缺失的第一个正数|Hard题O(n)+O(1)最优解法深度解析
java·算法·leetcode·排序算法
Tongzhi202611 小时前
从部署到运维:通芝科技无感考勤一体机的全流程效率解析
运维·数据结构·科技·算法·贪心算法
Wang's Blog12 小时前
AI Agent白手起家30: 动态示例选择器之根据长度选择 Few Shot 示例
算法
oyguyteggytrrwwwrt13 小时前
自制交叉线路识别算法
算法
手写码匠13 小时前
华为云Flexus+DeepSeek征文|Dify 多智能体协同编排实战:R1 规划 + V3 执行,构建企业 Agent 团队
人工智能·深度学习·算法·aigc
晓天衡宇•评测社区14 小时前
FSR-Bench 前沿科学推理榜单发布:GPT-5.5 居首,“会推理”未必“能答对”
算法
程序喵大人15 小时前
【C++进阶】STL算法与函数对象 - 02 sort为什么需要随机访问迭代器
开发语言·c++·算法
hanlin0315 小时前
动态规划专练:力扣第121、122题
笔记·算法·leetcode
To_OC16 小时前
LC 74 搜索二维矩阵:换皮的二分查找,我居然一开始没看出来
javascript·算法·leetcode