当前位置: 首页 > news >正文

5.1 位运算专题:LeetCode 面试题 01.01. 判定字符是否唯一

1. 题目链接

LeetCode 面试题 01.01. 判定字符是否唯一


2. 题目描述

实现一个算法,确定一个字符串的所有字符是否全部唯一(即没有重复字符)。要求如下:

  • 不使用额外的数据结构(如哈希表)
  • 字符串仅包含小写字母 a-z

示例

  • 输入:"abc" → 输出:true
  • 输入:"aba" → 输出:false

3. 示例分析
  1. 无重复字符
    • "leetcode"false'e'重复)
    • "abc"true
  2. 边界情况
    • 空字符串 ""true
    • 字符串长度超过 26 → false(26 个小写字母最多只能有 26 个唯一字符)

4. 算法思路

核心思想位图法(Bitmask)

  1. 位图表示
    • 使用一个整数 flag 的二进制位表示字符是否出现过。
    • 每个二进制位对应一个小写字母,例如:
      • a → 第 0 位
      • b → 第 1 位
      • z → 第 25 位
  2. 遍历字符串
    • 若当前字符对应的二进制位为 1,说明已重复,返回 false
    • 否则,将该位设为 1,继续检查下一个字符。

优化点

  • 预判长度超过 26:若字符串长度超过 26,直接返回 false(鸽巢原理)。
  • 时间复杂度:O(n),空间复杂度:O(1)(仅需一个整数)。

5. 边界条件与注意事项
  1. 字符串长度
    • 若长度超过 26,直接返回 false
    • 空字符串直接返回 true
  2. 字符范围
    • 题目假设字符均为小写字母,若存在其他字符(如大写字母或符号),需预处理为小写。
  3. 位运算溢出
    • 移位操作 1 << ii 的范围需为 0~25,否则可能导致整数溢出。

6. 代码实现
class Solution {
public:
    bool isUnique(string astr) 
    {
        if (astr.size() > 26) return false; // 鸽巢原理优化
        
        int flag = 0; // 位图初始化
        for (char ch : astr) 
        {
            int i = ch - 'a'; // 计算字符对应的二进制位
            if ((flag >> i) & 1) 
            { // 判断该位是否为1
                return false;
            }
            flag |= (1 << i); // 将该位设为1
        }
        return true;
    }
};

与其他方法的对比

方法时间复杂度空间复杂度适用场景
位图法O(n)O(1)仅限小写字母
哈希表法O(n)O(26)所有字符类型
数组计数法O(n)O(26)字符范围明确且较小
暴力枚举法O(n²)O(1)极短字符串(n ≤ 10)

关键代码解析

  1. 位运算检查重复

    if ((flag >> i) & 1) // 判断第i位是否为1
    
    • flag 右移 i 位后,与 1 按位与,结果为 1 则说明该位已被占用。
  2. 位图更新

    flag |= (1 << i); // 将第i位设为1
    
    • 1 左移 i 位后,与 flag 按位或,确保第 i 位被标记为已使用。

总结

位图法通过巧妙的位运算,将空间复杂度降至 O(1),同时保持线性时间复杂度。在面对限定字符范围的问题时(如小写字母、数字等),位图法是最优解之一。其核心在于将字符映射到整数的二进制位上,利用位运算的原子性快速判断重复性。实际应用中,需注意字符范围与整数位数的限制(例如,32 位整数最多覆盖 32 种字符)。

相关文章:

  • QT编程之PCM音频播放与采集
  • vue3 项目的最新eslint9 + prettier 配置
  • Android获取U盘路径
  • Python+Requests+Pytest+YAML+Allure接口自动化框架
  • 从国家能源到浙江交通投资,全息技术在能源交通领域的创新应用
  • Spring 框架基础教程(Day03)
  • JVM 01
  • C++菜鸟教程 - 从入门到精通 第五节
  • 隔空打印,IPP,IPD,HP Jetdirect协议的区别(Mac添加打印机四种协议的区别)
  • 【Unity】合批处理和GPU实例化的底层优化原理(完)
  • Spring 框架中的 BeanUtils
  • AugFPN
  • STM32标准库开发中断流程
  • 编译原理 pl0 词法解析器 使用状态机与状态矩阵,和查找上一步得到分析
  • Windows下rust的安装
  • python 中match...case 和 C switch case区别
  • 数据库联表Sql语句建一个新表(MySQL,Postgresql,SQL server)
  • Linux开机、重启与用户登录注销全解析
  • C++之模板二番战
  • Spring Boot事件机制详解
  • 甘肃白银煤矿透水事故仍有3人失联,现场约510立方米煤泥拥堵巷道
  • 印军称中国向巴基斯坦提供防空系统协助,外交部:中方十分重视与印、巴两国关系
  • 雷军:小米芯片采用3纳米制程,首款SUV“YU7”即将发布
  • 高温最强时段来了!北方局地高温有明显极端性
  • 视频丨为救心梗同学缺席职教高考的小伙姜昭鹏完成补考
  • 商务部:对原产于美国、欧盟、台湾地区和日本的进口共聚聚甲醛征收反倾销税