【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;
    }
}
相关推荐
rannn_1111 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
leisoo80971 小时前
100GBA股股票数据怎么存ClickHouseRedisMySQLJSON完整对比
大数据·linux·服务器·开发语言·python
不会代码的小猴2 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
营养充电站2 小时前
VS Code Git 工作树:解锁多分支并行开发的高效体验
leetcode·决策树·逻辑回归·散列表·模拟退火算法
IKUN家族2 小时前
Spring IoC&DI
java·spring·rpc
一只旭宝3 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
良木林3 小时前
子串 - LeetCode hot 100
算法·leetcode·职场和发展
蒸蒸yyyyzwd4 小时前
秋招不熟悉力扣学习笔记1
笔记·学习·leetcode
山荷枝4 小时前
03-框架--Spring
java·后端·spring
ChaHae-In4 小时前
SpringBoot统一功能处理
java·spring boot·后端