【LeetCode精选算法】位运算专题一

目录

题目一:判断字符是否唯一(Easy)

题目链接

解题思路(位图法)

Java代码实现

题目二:丢失的数字(Easy)

题目链接

解题思路(位运算---异或消消乐)

Java代码实现

题目三:两整数之和(Medium)

题目链接

解题思路(位运算模拟加法)

Java代码实现

[题目四:只出现一次的数字 II(Medium)](#题目四:只出现一次的数字 II(Medium))

题目链接

解题思路(比特位计数)

Java代码实现


题目一:判断字符是否唯一(Easy)

题目链接

解题思路(位图法)

  1. 鸽巢原理优化 :如果字符串长度超过 26(小写字母总数),则必定有重复字符,直接返回 false。

  2. 位图思想:

    • 使用一个 32 位的整数 bitMap 作为"哈希表",每一位代表一个小写字母(0 表示未出现,1 表示已出现)。

    • 遍历字符串每个字符 ch,计算其偏移量 i = ch - 'a'。

    • 检查 bitMap 的第 i 位是否为 1:

      • 若为 1,说明字符已出现,返回 false。

      • 否则,将第 i 位置为 1(通过 bitMap |= 1 << i)。

  3. 遍历结束未发现重复,返回 true。

Java代码实现

java 复制代码
class Solution {
    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;
    }
}

题目二:丢失的数字(Easy)

题目链接

解题思路(位运算---异或消消乐)

  1. 异或运算性质:

    • 任何数与 0 异或等于其本身:a ^ 0 = a

    • 相同数异或结果为 0:a ^ a = 0

    • 异或满足交换律和结合律

  2. 算法步骤:

    • 初始化 ret = 0。

    • 遍历数组 nums,将每个数与 ret 异或。

    • 再遍历 [0, n](n 为数组长度),将每个数与 ret 异或。

    • 最终 ret 即为缺失的数字(因为出现两次的数都抵消了,缺失的数只出现一次)。

Java代码实现

java 复制代码
class Solution {
    public int missingNumber(int[] nums) {
        int ret = 0;
        // 异或数组中的所有数
        for (int x : nums) {
            ret ^= x;
        }
        // 异或 [0, n] 的所有数
        for (int i = 0; i <= nums.length; i++) {
            ret ^= i;
        }
        return ret;
    }
}

题目三:两整数之和(Medium)

题目链接

解题思路(位运算模拟加法)

  1. 异或运算 :a ^ b 得到无进位加法的结果。

  2. 与运算 :(a & b) << 1 得到进位。

  3. 循环处理:

    • 将无进位加法结果赋给 a,进位赋给 b。

    • 重复直到进位 b 为 0,此时 a 即为最终和。

  4. 注意:Java 中负数用补码表示,位运算同样适用。

Java代码实现

java 复制代码
class Solution {
    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;
    }
}

题目四:只出现一次的数字 II(Medium)

题目链接

解题思路(比特位计数)

  1. 位运算统计:

    • 由于其他数字都出现了三次,我们可以统计每个比特位上 1 出现的次数。

    • 对每一位的计数结果取模 3,得到的结果就是只出现一次的数字在该位上的值(0 或 1)。

  2. 算法步骤:

    • 初始化 ret = 0。

    • 遍历 32 个比特位(int 有 32 位):

      • 统计数组中所有数字在该位上 1 的个数 sum。

      • 如果 sum % 3 == 1,说明只出现一次的数字在该位上是 1,将 ret 的该位置为 1。

    • 最终 ret 即为所求。

Java代码实现

java 复制代码
class Solution {
    public int singleNumber(int[] nums) {
        int ret = 0;
        // 遍历32个比特位
        for (int i = 0; i < 32; i++) {
            int sum = 0;
            // 统计第i位上1的个数
            for (int x : nums) {
                if (((x >> i) & 1) == 1) {
                    sum++;
                }
            }
            sum %= 3;
            if (sum == 1) {
                ret |= (1 << i); // 设置ret的第i位为1
            }
        }
        return ret;
    }
}
相关推荐
卓怡学长1 分钟前
w192基于springboot“考研情报站”微信小程序设计与实现
java·spring boot·spring·微信小程序·intellij-idea
wuminyu12 分钟前
JEP491中synchronized关键字引发的平台线程钉住解决方法简介
java·linux·c语言·jvm·c++
可乐鸡翅yeah_17 分钟前
fmp4 碎片 MP4 格式 HLS 流,和传统 TS 分片有什么不一样
开发语言·javascript·ios·音视频·safari·m3u8·m3u8在线播放
流形填表20 分钟前
多校区题库标准化:Excel模板与校验脚本
开发语言·python
All for pursuit.21 分钟前
【贪心-4】581.最短无序连续子数组
数据结构·c++·算法·leetcode
步行cgn28 分钟前
AOP 通知的类型详解
开发语言
weixin_3077791331 分钟前
从“人操作仪器”到“Agent 自主发现”:OPL 金属材料自驱动实验室 MVP 技术论述
开发语言·人工智能·算法·架构
笑鸿的学习笔记1 小时前
C++笔记之SIMD与SSE指令集
开发语言·c++·笔记
anew___1 小时前
《从零手写操作系统 (20):ELF加载器——让OS读懂现代编译器》
java·服务器·前端
code2cat1 小时前
【随笔】MCP资源更新订阅:通知到达以后,Agent怎样刷新旧资料
java·后端·开发工具·ai agent·mcp