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

目录

[1. 判断字符是否唯一(面试题 01.01)](#1. 判断字符是否唯一(面试题 01.01))

解题思路

[Java 代码](#Java 代码)

[2. 丢失的数字(268)](#2. 丢失的数字(268))

解题思路

[Java 代码](#Java 代码)

[3. 两整数之和(371)](#3. 两整数之和(371))

解题思路

[Java 代码](#Java 代码)

[4. 只出现一次的数字 II(137)](#4. 只出现一次的数字 II(137))

解题思路

[Java 代码](#Java 代码)

[5. 消失的两个数字(面试题 17.19)](#5. 消失的两个数字(面试题 17.19))

解题思路

[Java 代码](#Java 代码)


1. 判断字符是否唯一(面试题 01.01)

解题思路
  • 利用鸽巢原理优化:若字符串长度大于 26(小写字母总数),直接返回 false。
  • 位图思想:用一个 int 类型变量(32 位)充当哈希表,每个比特位对应一个小写字母。比特位为 0 表示字符未出现,为 1 表示已出现。
  • 遍历字符串时,通过字符与 'a' 的差值确定对应比特位,先判断该比特位是否为 1(已出现),若否则将该比特位置为 1。
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;
    }
}

2. 丢失的数字(268)

解题思路
  • 设数组大小为 n,完整范围是 [0, n],数组是该范围缺失一个数后的序列。
  • 利用异或运算的 "消消乐" 特性:相同数字异或结果为 0,0 与任意数字异或结果为该数字。
  • 将数组中所有元素与 [0, n] 中所有数字逐一异或,最终结果即为缺失的数字。
Java 代码
java 复制代码
class Solution {
    public int missingNumber(int[] nums) {
        int ret = 0;
        for (int x : nums) ret ^= x;
        for (int i = 0; i <= nums.length; i++) ret ^= i;
        return ret;
    }
}

3. 两整数之和(371)

解题思路
  • 异或(^)运算本质是 "无进位加法",可得到两数相加不考虑进位的结果。
  • 按位与(&)运算可得到两数相加产生进位的位置,左移 1 位后即为进位值。
  • 循环执行 "无进位加法" 和 "计算进位" 操作,直到进位值为 0,此时的无进位加法结果即为最终和。
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;
    }
}

4. 只出现一次的数字 II(137)

解题思路
  • 数组中除目标元素外,其余元素均出现三次,目标元素仅出现一次。
  • 统计所有数字每个比特位上 1 的总和,总和对 3 取余,结果为 1 则说明目标元素该比特位为 1,否则为 0。
  • 遍历 32 位整数的每一位,按上述规则还原目标元素的每一位,最终得到目标元素。
Java 代码
java 复制代码
class Solution {
    public int singleNumber(int[] nums) {
        int ret = 0;
        for (int i = 0; i < 32; i++) { // 依次修改 ret 中的每一个比特位
            int sum = 0;
            for (int x : nums) { // 统计 nums 中所有的数的第i位的和
                if (((x >> i) & 1) == 1) {
                    sum++;
                }
            }
            sum %= 3;
            if (sum == 1) {
                ret |= 1 << i;
            }
        }
        return ret;
    }
}

5. 消失的两个数字(面试题 17.19)

解题思路
  • 结合 "丢失的数字" 和 "只出现一次的数字 III" 的思路:先将数组元素与 [1, n+2](n 为数组长度)的所有数字异或,得到两个消失数字的异或结果(其余数字均出现两次,异或后抵消)。
  • 找到异或结果中任意一个为 1 的比特位(该位表示两个消失数字在该位上的值不同)。
  • 根据该比特位将所有数字(数组元素 +[1, n+2])分为两组,每组内仅包含一个消失数字,分别对两组异或,得到两个消失数字。
Java 代码
java 复制代码
class Solution {
    public int[] missingTwo(int[] nums) {
        // 1. 先把所有的数异或在一起
        int tmp = 0;
        for (int x : nums) tmp ^= x;
        for (int i = 1; i <= nums.length + 2; i++) tmp ^= i;
        
        // 2. 找出a,b两个数比特位不同的那一位
        int diff = 0;
        while (true) {
            if (((tmp >> diff) & 1) == 1) break;
            else diff++;
        }
        
        // 3. 将所有的数按照diff位不同,分两类异或
        int[] ret = new int[2];
        for (int x : nums) {
            if (((x >> diff) & 1) == 1) ret[1] ^= x;
            else ret[0] ^= x;
        }
        for (int i = 1; i <= nums.length + 2; i++) {
            if (((i >> diff) & 1) == 1) ret[1] ^= i;
            else ret[0] ^= i;
        }
        return ret;
    }
}
相关推荐
机器视觉的发动机10 分钟前
AI算力中心的能耗挑战与未来破局之路
开发语言·人工智能·自动化·视觉检测·机器视觉
铁蛋AI编程实战14 分钟前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
HyperAI超神经18 分钟前
在线教程|DeepSeek-OCR 2公式/表格解析同步改善,以低视觉token成本实现近4%的性能跃迁
开发语言·人工智能·深度学习·神经网络·机器学习·ocr·创业创新
晚霞的不甘25 分钟前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
马猴烧酒.25 分钟前
【面试八股|JVM虚拟机】JVM虚拟机常考面试题详解
jvm·面试·职场和发展
SunnyDays101127 分钟前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
R_.L28 分钟前
【QT】常用控件(按钮类控件、显示类控件、输入类控件、多元素控件、容器类控件、布局管理器)
开发语言·qt
喵叔哟36 分钟前
06-ASPNETCore-WebAPI开发
服务器·后端·c#
Zach_yuan37 分钟前
自定义协议:实现网络计算器
linux·服务器·开发语言·网络
摇滚侠38 分钟前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea