【OJ题解】在字符串中查找第一个不重复字符的索引

news/2024/11/5 22:48:54 标签: c++, leetcode, c
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="markdown_views prism-tomorrow-night"> cap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

💵个人主页: 起名字真南
💵个人专栏:【数据结构初阶】 【C语言】 【C++】 【OJ题解】

c="https://i-blog.csdnimg.cn/direct/69fd2d5f461d4d94b24b6a5799cae5c8.gif#pic_center" alt="请添加图片描述" />

class="toc">

目录

  • 1. 引言
  • 2. 题目分析
    • 示例:
  • 3. 解题思路
    • 思路一:双重循环
    • 思路二:哈希表
  • 4. C++代码实现
  • 5. 代码详解
  • 6. 时间和空间复杂度分析
  • 7. 优化方法
    • 使用哈希表优化的思路:
  • 8. 时间和空间复杂度分析(哈希表实现)
  • 9. 总结

1. 引言

ckquote>

在字符串处理相关问题中࿰c;查找第一个不重复字符的索引是一个经典题目。特别是在高并发环境中࿰c;我们可能需要高效判断某个字符串的字符是否有重复。本文将详细解析如何在给定字符串中找到第一个不重复字符的索引。

ckquote>

2. 题目分析

给定一个字符串 <code>scode>࿰c;需要找到第一个不重复字符的索引。如果不存在不重复字符࿰c;则返回 <code>-1code>。

在字符串中查找第一个不重复字符的索引题目链接

示例:

  • 示例 1:
    • 输入:<code>s = "class="tags" href="/tags/LEETCODE.html" title=leetcode>leetcode"code>
    • 输出:<code>0code>(因为第一个不重复字符是 <code>lcode>࿰c;索引为 0)
  • 示例 2:
    • 输入:<code>s = "loveclass="tags" href="/tags/LEETCODE.html" title=leetcode>leetcode"code>
    • 输出:<code>2code>(第一个不重复字符是 <code>vcode>࿰c;索引为 2)
  • 示例 3:
    • 输入:<code>s = "aabb"code>
    • 输出:<code>-1code>(所有字符都重复)

3. 解题思路

这道题可以通过双重循环哈希表两种思路来实现。双重循环简单直接࿰c;但在处理大型字符串时效率较低。本文将以双重循环方法为主࿰c;之后讨论优化方法。

思路一:双重循环

我们逐个检查字符串中的每个字符࿰c;并在整个字符串中寻找其他相同字符。若发现相同字符࿰c;则跳过;否则࿰c;返回该字符的索引。

思路二:哈希表

可以用哈希表记录每个字符出现的次数。之后再遍历字符串࿰c;查找第一个只出现一次的字符。

4. C++代码实现

以下为C++代码࿰c;使用双重循环来实现第一个不重复字符的查找:

<code class="prism language-cpp">class="token keyword">class class="token class-name">Solution class="token punctuation">{
class="token keyword">publicclass="token operator">:
    class="token keyword">int class="token function">firstUniqCharclass="token punctuation">(string sclass="token punctuation">) class="token punctuation">{
        class="token keyword">int len class="token operator">= sclass="token punctuation">.class="token function">sizeclass="token punctuation">(class="token punctuation">)class="token punctuation">;
        class="token comment">// 遍历字符串中的每个字符
        class="token keyword">for class="token punctuation">(class="token keyword">int i class="token operator">= class="token number">0class="token punctuation">; i class="token operator">< lenclass="token punctuation">; iclass="token operator">++class="token punctuation">) class="token punctuation">{
            class="token keyword">bool isUnique class="token operator">= class="token boolean">trueclass="token punctuation">; class="token comment">// 假设当前字符是唯一的
            class="token keyword">for class="token punctuation">(class="token keyword">int j class="token operator">= class="token number">0class="token punctuation">; j class="token operator">< lenclass="token punctuation">; jclass="token operator">++class="token punctuation">) class="token punctuation">{
                class="token comment">// 检查是否有其他相同字符
                class="token keyword">if class="token punctuation">(sclass="token punctuation">[iclass="token punctuation">] class="token operator">== sclass="token punctuation">[jclass="token punctuation">] class="token operator">&& i class="token operator">!= jclass="token punctuation">) class="token punctuation">{
                    isUnique class="token operator">= class="token boolean">falseclass="token punctuation">;
                    class="token keyword">breakclass="token punctuation">;
                class="token punctuation">}
            class="token punctuation">}
            class="token comment">// 如果是唯一字符࿰c;返回其索引
            class="token keyword">if class="token punctuation">(isUniqueclass="token punctuation">) class="token punctuation">{
                class="token keyword">return iclass="token punctuation">;
            class="token punctuation">}
        class="token punctuation">}
        class="token keyword">return class="token operator">-class="token number">1class="token punctuation">; class="token comment">// 没有找到不重复字符
    class="token punctuation">}
class="token punctuation">}class="token punctuation">;
code>

5. 代码详解

  • 外层循环:遍历字符串中的每一个字符 <code>s[i]code>࿰c;并假设该字符是唯一的。
  • 内层循环:检查 <code>s[i]code> 是否在其他位置出现:
    • 如果找到与 <code>s[i]code> 相同的字符࿰c;则将 <code>isUniquecode> 标记为 <code>falsecode>࿰c;并跳出内层循环。
  • 返回索引:如果 <code>isUniquecode> 仍然为<code>truecode>࿰c;表示当前字符是唯一的࿰c;返回它的索引<code>icode>。
  • 返回-1:如果遍历结束没有找到不重复字符࿰c;返回 <code>-1code>。

6. 时间和空间复杂度分析

  • 时间复杂度:O(n^2)࿰c;其中 <code>ncode> 是字符串的长度。外层循环遍历字符串中的每个字符࿰c;内层循环遍历整个字符串来寻找重复字符࿰c;因此时间复杂度为 O(n^2)。
  • 空间复杂度:O(1)࿰c;仅使用了常数级额外空间。

7. 优化方法

尽管双重循环方法简单易懂࿰c;但在长字符串中效率较低。可以使用哈希表优化到线性时间复杂度。

使用哈希表优化的思路:

  1. 首次遍历字符串࿰c;将每个字符的出现次数记录到哈希表中。
  2. 再次遍历字符串࿰c;找到第一个只出现一次的字符并返回其索引。

优化后的代码如下:

<code class="prism language-cpp">class="token macro property">class="token directive-hash">#class="token directive keyword">include class="token string"><unordered_map>

class="token keyword">class class="token class-name">Solution class="token punctuation">{
class="token keyword">publicclass="token operator">:
    class="token keyword">int class="token function">firstUniqCharclass="token punctuation">(string sclass="token punctuation">) class="token punctuation">{
        unordered_mapclass="token operator"><class="token keyword">charclass="token punctuation">, class="token keyword">intclass="token operator">> countMapclass="token punctuation">;
        class="token comment">// 统计每个字符出现的次数
        class="token keyword">for class="token punctuation">(class="token keyword">char c class="token operator">: sclass="token punctuation">) class="token punctuation">{
            countMapclass="token punctuation">[cclass="token punctuation">]class="token operator">++class="token punctuation">;
        class="token punctuation">}
        class="token comment">// 再次遍历字符串࿰c;找到第一个只出现一次的字符
        class="token keyword">for class="token punctuation">(class="token keyword">int i class="token operator">= class="token number">0class="token punctuation">; i class="token operator">< sclass="token punctuation">.class="token function">sizeclass="token punctuation">(class="token punctuation">)class="token punctuation">; iclass="token operator">++class="token punctuation">) class="token punctuation">{
            class="token keyword">if class="token punctuation">(countMapclass="token punctuation">[sclass="token punctuation">[iclass="token punctuation">]class="token punctuation">] class="token operator">== class="token number">1class="token punctuation">) class="token punctuation">{
                class="token keyword">return iclass="token punctuation">;
            class="token punctuation">}
        class="token punctuation">}
        class="token keyword">return class="token operator">-class="token number">1class="token punctuation">;
    class="token punctuation">}
class="token punctuation">}class="token punctuation">;
code>

8. 时间和空间复杂度分析(哈希表实现)

  • 时间复杂度:O(n)࿰c;因为哈希表方法只需要两次遍历字符串。
  • 空间复杂度:O(1)࿰c;因为哈希表中的键值对不会超过字符数量。

9. 总结

本文介绍了如何查找字符串中第一个不重复字符的索引。虽然双重循环方法能有效解决问题࿰c;但在大型数据下不够高效。哈希表优化方法可以大幅提升效率࿰c;适用于各种字符串长度。希望通过此文章能帮助大家更好地理解字符串不重复字符查找的实现。

今后可以探索更多优化方法࿰c;如基于字符ASCII码的统计数组࿰c;以实现更快的查找操作。


http://www.niftyadmin.cn/n/5739919.html

相关文章

在 Windows 中简化 Nginx 命令行操作

本文的主要目的是为了实现打开命令行后可以直接运行 Nginx 的常用命令&#xff0c;不需要手动切换到工作目录&#xff0c;从而简化操作流程。 1. 背景 在 Windows 中运行 Nginx 每次都需要进入安装目录&#xff0c;运行 Nginx 工具&#xff1a; 直接将 Nginx 的安装目录添加到…

spring ai 入门 之 结构化输出 - 把大模型llm返回的内容转换成java bean

目录 ​编辑 将AI非结构化文本转换为特定格式数据的应用场景说明 Spring AI 介绍 &#xff1a;为Java开发者打造的AI应用开发框架 Qwen 介绍 &#xff1a; 一个国内领先的开源大模型 Spring AI Alibaba框架介绍 &#xff1a; 一个国内最好的spring ai实现 使用spring ai …

deepfm模型实现招聘职位推荐算法

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

git查看历史提交中文件的变化

在版本控制系统中&#xff0c;Git以其强大的日志和差异分析功能而闻名。这些功能帮助开发者追踪文件的变更历史和理解代码的演进。本文将深入探讨四个Git命令&#xff1a;git log --name-only、git log --name-status和git diff-tree --no-commit-id --name-status -r、git sho…

深度学习之数据增强

1 深度学习中常用的数据增强方法&#xff1f; Color Jittering&#xff1a;对颜色的数据增强&#xff1a;图像亮度、饱和度、对比度变化&#xff08;此处对色彩抖动的理解不知是否得当&#xff09;&#xff1b; PCA Jittering&#xff1a;首先按照RGB三个颜色通道计算均值和标…

【万字详文介绍】:迭代扩张卷积神经网络(IDCNN)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

如何取消Outlook中的循环会议

如何取消Outlook中的循环会议 参考链接&#xff1a;https://iknow.lenovo.com.cn/detail/195430 1、打开Outlook&#xff0c;进入 日历 视图界面&#xff1b; 2、 选择并双击要取消的循环会议&#xff1b; 3、 在 打开定期项目 对话框中选择整个序列&#xff0c;然后单击 确…

电机轴设计的技术参数研究

电机轴作为电机的关键组件之一&#xff0c;其设计不仅关系到电机的性能和效率&#xff0c;还直接影响到整个机械系统的可靠性与使用寿命。电机轴的设计涉及众多技术参数&#xff0c;这些参数通常包括但不限于尺寸参数、材料选择、强度分析、转动平衡、轴承选择以及制造公差等。…