【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;
    }
}
相关推荐
system_error_x35 分钟前
C++ 编程基础入门教程
开发语言·c++
旋律41438 分钟前
同义方法区别(增加类与删除类)
java·后端
Amos_Web39 分钟前
Markdonw语法
开发语言·前端·javascript
学到老活到老40 分钟前
方法执行完了,对象为什么还占着内存?
java·jvm
用户77712985091240 分钟前
常见的同义方法的区别:增加类和删除类
java·后端
十年Java程序媛1 小时前
Java this 与 super 详解|继承高频踩坑 + 面试题整理
java·spring boot·面试
用户7771298509121 小时前
Stream流式使用
java
旋律4141 小时前
List、Set、Map:三个装数据的容器,到底啥区别?怎么遍历?
java·后端
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 回顾和今日内容介绍
java·开发语言·交友