LeetCode 387. 字符串中的第一个唯一字符

2023-05-16

题目

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

详见:387. 字符串中的第一个唯一字符

思路

  1. 哈希存储出现次数,第一次遍历字符串,存储每个字符出现的次数,第二次遍历字符串,如果该字符只出现一次,则返回它的索引
  2. find函数,rfind() 从后向前查找字符第一次出现的位置,find() 从前向后查找字符第一次出现的位置,遍历字符串,如果字符的第一个索引和最后一个索引是同一个位置,则返回该索引

队列,也可以借助队列找到第一个不重复的字符,队列具有「先进先出」的性质,因此很适合用来找出第一个满足某个条件的元素。使用一个额外的队列,按照顺序存储每一个字符以及它们第一次出现的位置。对字符串进行遍历时,设当前遍历到的字符为 c,如果 c 不在哈希映射中,我们就将 c
与它的索引作为一个二元组放入队尾,否则我们就需要检查队列中的元素是否都满足「只出现一次」的要求,即我们不断地根据哈希映射中存储的值(是否为−1)选择弹出队首的元素,直到队首元素「真的」只出现了一次或者队列为空。在遍历完成后,如果队列为空,说明没有不重复的字符,返回−1,否则队首的元素即为第一个不重复的字符以及其索引的二元组。在维护队列时,我们使用了「延迟删除」这一技巧。也就是说,即使队列中有一些字符出现了超过一次,但它只要不位于队首,那么就不会对答案造成影响,我们也就可以不用去删除它。只有当它前面的所有字符被移出队列,它成为队首时,我们才需要将它移除。
来源:LeetCode

代码

方法一:哈希存储出现次数

class Solution {
public:
    int firstUniqChar(string s) {
        unordered_map<int, int>str;
        for(auto ch : s){
            str[ch]++;
        }
        for(int i = 0; i < s.size(); i++){
            if(str[s[i]] == 1){
                return i;
            }
        }
        return -1;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(∣Σ∣)

方法二: find函数

class Solution {
public:
    int firstUniqChar(string s) {
        for(int i = 0; i < s.size(); i++){
            if(s.find(s[i]) == s.rfind(s[i])){
                return i;
            }
        }
        return -1;
    }
};

方法三:队列

class Solution {
public:
    int firstUniqChar(string s) {
        unordered_map<char, int> position;
        queue<pair<char, int>> q;
        int n = s.size();
        for (int i = 0; i < n; ++i) {
            if (!position.count(s[i])) {
                position[s[i]] = i;
                q.emplace(s[i], i);
            }
            else {
                position[s[i]] = -1;
                while (!q.empty() && position[q.front().first] == -1) {
                    q.pop();
                }
            }
        }
        return q.empty() ? -1 : q.front().second;
    }
};

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode 387. 字符串中的第一个唯一字符 的相关文章

  • 9:JDBC-Java API 实战

    目录 1 说明2 JDBC的由来以及定义3 JDBC体验 xff0c statement executeQuery 查询4 整理和释放5 封装JDBCUtils6 增删改 executeUpdate 7 字符编码问题8 PreparedSt
  • 10:Java人脸识别认证-Java API 实战

    目录 1 提出问题 xff0c 引入SDK的概念2 选择平台3 SDK下载和文档说明4 人脸检测5 人脸对比6 建议和结束语 1 提出问题 xff0c 引入SDK的概念 什么是SDK xff1f 我们并不具备开发人脸识别的能力 xff0c
  • 个人学习笔记附Markdown格式下载

    B S方向 文章链接 xff1a https blog csdn net qq 46207024 article details 114378676 spm 61 1001 2014 3001 5502 下载链接 xff1a https d
  • Ubuntu/Linux 访问 Windows 共享文件夹

    文章目录 Ubuntu Linux 访问 Windows 共享文件夹SMB 协议安装 samba 客户端访问共享文件夹参考资料 Ubuntu Linux 访问 Windows 共享文件夹 SMB 协议 Linux 操作系统与 Windows
  • Java 序列化与反序列化

    目录 一 说明二 理解三 实现1 实现接口2 序列化方法3 反序列化方法 一 说明 序列化与反序列化是什么 序列化 xff1a 将Java对象表示为一个字节序列 xff0c 存储对象数据到文件中 xff0c 可用于网络传输 反序列化 xff
  • JavaMail 使用POP3/SMTP服务发送QQ邮件

    目录 一 说明二 理解三 实现1 导入jar包2 用户认证3 发送邮件创建步骤简单的Email带HTML的E mail带图片的Email包含附件的邮件 一 说明 邮件服务器 为用户提供接收邮件的功能 xff0c 有发邮件的SMTP服务器 x
  • Java多线程 Callable和Future

    目录 一 说明二 理解三 实现1 实现接口2 执行线程 一 说明 Java 提供了三种创建线程的方法 实现 Runnable接口继承 Thread类本身通过 Callable和 Future 创建线程 Callable和Future的引入
  • Java多线程 Future和FutureTask的区别

    目录 一 说明二 理解三 实现1 实现接口2 使用Future3 使用FutureTask 一 说明 Future和FutureTask的关系 Future 是一个接口 xff0c 无法直接创建对象 xff0c 需配合线程池使用 submi
  • Java多线程 CompletionService和ExecutorCompletionService

    目录 一 说明二 理解三 实现1 使用Future2 使用ExecutorCompletionService3 take 方法4 poll 方法5 poll long timeout TimeUnit unit 方法 一 说明 Future
  • Java多线程 线程池Executor框架

    目录 一 说明二 理解ExecutorExecutorServiceExecutors 三 实现1 newSingleThreadExecutor2 newFixedThreadPool3 newCachedThreadPool4 newS
  • Java多线程 ThreadPoolExecutor自定义线程池

    目录 一 说明二 理解三 实现1 SynchronousQueue2 ArrayBlockingQueue3 LinkedBlockingQueue 一 说明 ThreadPoolExecutor Java提供的线程池Executor框架相
  • Java多线程 ThreadPoolExecutor-RejectedExecutionHandler拒绝执行策略

    目录 一 说明二 理解三 实现1 AbortPolicy2 DiscardPolicy3 DiscardOldestPolicy4 CallerRunsPolicy5 自定义拒绝执行策略 一 说明 RejectedExecutionHand
  • Java多线程 关闭线程池 shutdown() 、shutdownNow()、awaitTermination()

    目录 一 说明二 理解三 实现1 shutdown 2 shutdownNow 3 awaitTermination 一 说明 ThreadPoolExecutor 继承 Executor 接口它有多个构造方法来实现自定义创建线程池 xff
  • Java多线程 线程池的生命周期及运行状态

    目录 一 说明二 理解三 实现 一 说明 线程池的生命周期 线程池的状态runState和工作线程数量workerCount共同保存在 AtomicInteger 类型的控制变量 ctl 中ctl高三位保存运行状态 23 61 8 gt 5
  • Unable to determine the device handle for GPU 0000:02:00.0: GPU is lost.

    TITAN X Pascal 的显卡 xff0c 当 batch size 过大爆显存时 xff0c 就会出现 GPU丢失 的错误
  • Java文档注释 Intellij IDEA Generate JavaDoc

    目录 一 说明二 理解三 实现 一 说明 文档注释 Java Doc Comments 是指允许你在程序中嵌入关于程序的信息 xff0c 使你更加方便的记录你的程序的信息你可以使用Javadoc工具软件来生成信息 xff0c 并输出到HTM
  • Java 泛型

    目录 一 说明二 理解三 实现1 泛型类2 泛型方法3 类型通配符 一 说明 泛型 generics 本质是参数化类型 xff0c 所操作的数据类型被指定为一个参数提供编译时类型安全检测机制 xff0c 允许程序员在编译时检测到非法的类型
  • STC51单片机-中断控制LED-物联网应用系统设计项目开发

    目录 一 说明二 重点三 实现四 下载 一 说明 单片机中 中断 处理主要是指单片机暂停当前主程序的执行 xff0c 而去执行更重要或需急迫处理的事件请求的处理程序 xff0c 处理完成后 xff0c 再回到主程序暂停处继续执行 这个事件叫
  • STC51单片机-阵列LED显示-物联网应用系统设计项目开发

    目录 一 说明二 重点三 实现四 下载 一 说明 大部分发光二极管工作电流15mA之间 xff0c 其内阻为20100 电流越大 xff0c 亮度也越高 单片机并行端口P1 xff5e P3驱动发光二极管 xff0c 可以采用图6 1电路
  • STC51单片机-多外部中断事件处理及应用-物联网应用系统设计项目开发

    目录 一 说明二 重点三 实现四 下载 一 说明 单片机中 中断 处理主要是指单片机暂停当前主程序的执行 xff0c 而去执行更重要或需急迫处理的事件请求的处理程序 xff0c 处理完成后 xff0c 再回到主程序暂停处继续执行 这个事件叫

随机推荐