【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;
    }
}
相关推荐
橙露2 小时前
CGO性能深度剖析:成因、评估与优化全指南
java·jvm·myeclipse
点云SLAM2 小时前
C++内存泄漏检测之编译期 /运行时工具(ASan/Valgrind)
开发语言·c++·内存管理·错误排查·内存泄漏检测工具·valgrind工具·asan工具
逍遥德2 小时前
Java Stream Collectors 用法
java·windows·python
leaves falling2 小时前
c语言-编译和链接
c语言·开发语言
YuTaoShao2 小时前
【LeetCode 每日一题】3507. 移除最小数对使数组有序 I
算法·leetcode·职场和发展
kk5792 小时前
【MATLAB R2018a】路径文件pathdef.m为只读文件无法保存到matlab启动文件夹的问题
开发语言·matlab
Getgit2 小时前
mysql批量更新语句
java·数据库·mysql·udp·eclipse
黎雁·泠崖2 小时前
Java静态变量底层:内存图解析+避坑指南
java·开发语言
布局呆星2 小时前
魔术方法与魔术变量
开发语言·python