【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;
    }
}
相关推荐
武子康4 分钟前
Java-22 深入浅出 MyBatis - 手写ORM框架3 手写SqlSession、Executor 工作原理
java·后端
断点之下7 分钟前
数据结构从零开始④:堆——一种特殊的完全二叉树(附堆排序、TopK问题)
数据结构
WL学习笔记9 分钟前
顺序表详解
c语言·数据结构
sugar__salt11 分钟前
深入吃透前端线性数据结构:数组、栈、队列、链表核心原理与实战
前端·数据结构·链表
未若君雅裁12 分钟前
JVM 垃圾回收算法与分代回收机制
java·jvm·算法
skywalk816320 分钟前
记录段言的开发过程
开发语言·学习·编程
摇滚侠28 分钟前
SpringMVC 入门到实战 简介和入门案例 01-13
java·后端·spring·intellij-idea
未若君雅裁28 分钟前
JVM 垃圾回收器全景与G1深度解析
java·开发语言·jvm
霸道流氓气质29 分钟前
Java 大数据量异步处理方案:线程池 vs 消息队列
java·开发语言
devilnumber29 分钟前
想真正吃透 + 灵活运用 Java 代理模式
java·开发语言·代理模式