【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;
    }
}
相关推荐
人工智能AI酱23 分钟前
【AI深究】逻辑回归(Logistic Regression)全网最详细全流程详解与案例(附大量Python代码演示)| 数学原理、案例流程、代码演示及结果解读 | 决策边界、正则化、优缺点及工程建议
人工智能·python·算法·机器学习·ai·逻辑回归·正则化
WangLanguager24 分钟前
逻辑回归(Logistic Regression)的详细介绍及Python代码示例
python·算法·逻辑回归
m0_5180194826 分钟前
C++与机器学习框架
开发语言·c++·算法
wefly201729 分钟前
m3u8live.cn 在线M3U8播放器,免安装高效验流排错
前端·后端·python·音视频·前端开发工具
ZTLJQ29 分钟前
深入理解逻辑回归:从数学原理到实战应用
开发语言·python·机器学习
一段佳话^cyx31 分钟前
详解逻辑回归(Logistic Regression):原理、推导、实现与实战
大数据·算法·机器学习·逻辑回归
qq_4176950533 分钟前
C++中的代理模式高级应用
开发语言·c++·算法
daidaidaiyu39 分钟前
Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML)
java·spring
xiaoye-duck1 小时前
《算法题讲解指南:动态规划算法--路径问题》--5.不同路径,6.不同路径II
c++·算法·动态规划
2403_835568471 小时前
自然语言处理(NLP)入门:使用NLTK和Spacy
jvm·数据库·python