leetcode 3. 最长不含重复的子字符串的五种解法

2023-11-12

leetcode链接:最长不含重复的子字符串

题目描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 

解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:

输入: s = "bbbbb"
输出: 1

解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:

输入: s = "pwwkew"
输出: 3

解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。

请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:

输入: s = ""
输出: 0

提示:

0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成

方法一

这道题可以用动态规划来解,思路解析:https://zhuanlan.zhihu.com/p/80538556

AC代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty())   return 0;
        int cur_len = 0;
        int max_len = 0;
        int tmp = -1;
        std::map<char, int> lastindex;
        for(auto i = 0; i < s.length(); i++)
        {
            if(lastindex.find(s[i]) == lastindex.end()) // not found
            {
                cur_len++;

            }
            else
            {
                tmp = i - lastindex[s[i]];
                if(tmp > cur_len)
                {
                    cur_len++;

                }
                else
                {
                    cur_len = tmp;

                }
            }
            max_len = max(max_len, cur_len);
            lastindex[s[i]] = i;
        }
        return max_len;
    }
};

方法二

思路解析:利用 hashset 来检查重复元素。

  • 我们定义 l 和 r 两个指针表示一个特定的子字符串的首和尾。初始它们都在索引 0 处。

  • 移动 r,并同时向 hashset 中添加 r 所指的元素值,当 r 指到重复的元素时,r - l 的值就是一个不含重复字符的子字符串的长度。

  • erase 掉 haseset 中的 l 所指元素的值,然后让 l++(for 循环的作用)。之后继续移动 r来找到下一个不含重复字符的子字符串的长度。

AC代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size()==0) return 0;
        unordered_set<char> store;
        int res=-1;
        int l=0,r=0;
        for(l=0;l<s.size();l++)
        {
            while(r<s.size()&&!store.count(s[r]))//set的count值只能是0或1
            {
                store.insert(s[r]);
                r++;
            }
            res=max(res,r-l);
            store.erase(s[l]);
            if(r>=s.size()) break;
        }
        return res;
    }
};

但因为涉及到频繁的元素erase,这个耗时会比第一种方法略高。

方法三

思路解析:使用滑动窗口来做。
窗口的范围为 [left, right],left,right初始化为0。
设置一个查找表 lookup,lookup 存储了当前窗口中的元素。right 先移动,如果 s[right] 不在 lookup 中,则 right++maxLen++,将 right 加入 lookup 中;否则,将 s[left]lookup 中移除(注意这里不是先移除重复的元素 s[right],因为先移除 s[right] 的话就不满足连续子串这个要求了),将 left++,直至 s[right] 不在 lookup 中出现。当遇到了重复字符,我们一步一步地移动 left 指针。为了加快速度,我们可以直接将 left 移动到当前 right 的位置上。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty()) return 0;
        vector<int> v(128, -1);
        int left = -1;
        int maxLen = 1;
        for(int right=0; right<s.size(); right++){
            char c = s[right];
            if(v[c]!=-1) left = max(left, v[c]);   // c 出现在了窗口中
            v[c] = right;
            maxLen = max(maxLen, right-left);
        }
        return maxLen;
    }
};

方法四
双指针,可以直接看代码和注释:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if (!s.size()) return 0; // 判空
        int maxLength = 0; // 记录最长不包含重复字符的子字符串的长度
        int left = 0, right = 0; // 初始化双指针
        unordered_set<char> subStr; // 哈希表存储不包含重复字符的子串
        /*
        *  双指针遍历原字符串:
        *  外层左指针、内层右指针
        */
        while (left < s.size()) {
            /*
            *  右指针不断右移遍历字符串
            *  当遇到的字符在哈希表中不存在时,将其插入哈希表
            *  遇到哈希表中存在的字符 或 到原字符串结尾时跳出循环
            */
            while (right < s.size() && !subStr.count(s[right])) {
                subStr.insert(s[right]);
                right++;
            }
            /*
            *  更新最大子串的长度
            *  因为上面的循环跳出时right指向的是子串后面一个位置
            *  所以是right-left而不是right-left+1
            */
            maxLength = max(maxLength, right - left);
            /*
            *  若上面循环跳出是因为右指针到原字符串末尾,
            *  说明遍历完毕,最长不包含重复字符的子串已经找到
            *  直接跳出循环
            */
            if (right == s.size()) break;
            /*
            *  若上面循环跳出是因为遇到了哈希表中已有的字符
            *  则从左边开始挨个删除哈希表中的字符
            *  并且左指针右移
            */
            subStr.erase(s[left]);
            left++;
        }
        return maxLength;
    }
};

方法五

背包

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> vec(128);
        int res = 0, beg = 0, len = s.size();
        for(int i = 1; i <= len; ++i) {
            auto &x = vec[s[i-1]];
            if(beg < x) { beg = x; }
            if(res < i - beg) { res = i - beg; }
            x = i;
        }
        return res;
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

leetcode 3. 最长不含重复的子字符串的五种解法 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定

随机推荐

  • 函数调用约定cdecl、stdcall、fastcall

    我们在编写代码的时候都会调用函数 有点函数有多个参数 例如 int test int a char b char c 上面的函数调用方式是test 10 c tinus 那么这个函数编译器是怎么知道有多少个参数 参数类型是什么了 因为函数调
  • 基于FPGA的LCD1602驱动(含代码)

    目录 LCD1602显示原理 LCD1602接口 LCD1602操作时序 1 读操作时序 2 写操作时序 LCD1602初始化 LCD1602读写数据 LCD1602显示原理 将LCD显示屏与FPGA连接之后 需要做的第一件事就是进行LCD
  • Redis底层封装细节

    日常我们程序员在使用redis做缓存的时候 很少会直接使用到RedisTemplate直接操作k v键值对 而是通过对RedisTemplate原生代码的封装 来构建我们日常便于使用习惯的代码来操作数据 这里我分享一下日常基本的对Redis
  • 【华为OD机试】矩阵元素的边界值【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 给定一个N M矩阵 请先找出M个该矩阵中每列元素的最大值 然后输出这M个值中的最小值 输入描述 无 输出描述 无 备注 N和M的取值范围均为 0 100 用例1 输入
  • umi+dva+antd后台管理系统(3)---完整登录逻辑

    源码在这儿MyGithub 觉得不错留颗小星星哦 界面准备好啦 开始写登录 1 回顾一下redux是什么 redux 是一个应用数据流框架 主要解决了组件间状态共享的问题 原理是集中式管理 可以让数据更可控 react 中所有数据处理都在
  • JS加减乘除位移方法封装

    常用加减乘除等方法汇总 直接上代码 逻辑简单 代码如下 div 加减乘除位移方法汇总 div
  • 轨迹预处理(轨迹压缩)

    轨迹压缩分为在线压缩和离线压缩两类 在介绍两类压缩算法之前 本文先介绍两种 距离度量 方法 第一种距离度量方法是 垂直的欧几里得距离 如图b所示 p1 p7 p12作为压缩后的点 垂直度量 则为做垂线计算 第二种距离度量方法是 时间同步的欧
  • Dynamics CRM2011 导入解决方案报根组件插入错误的解决方法

    今天在还原一个老版本的解决方案 在导入时报根组件插入问题 Cannot add a Root Component 38974590 9322 e311 b365 00155d810a00 of type 31 because it is n
  • android: ERROR: unknown virtual device nam

    环境变量 ANDROID SDK HOME your path 设置好就没有问题了
  • 刷脸支付服务商为各行各业提供完美体验

    随着刷脸支付技术迭代更新的速度加快 其商业化应用的步伐也越来越快了 4月17日 支付宝推出第二代基于线下消费场景的刷脸支付机具 蜻蜓2 0 定价1499元 同时 新一代蜻蜓还实现了刷脸注册会员卡的功能 切中了苦于获客高成本的线下零售门店的需
  • pve 使用noVNC num lock 不同步的问题

    问题描述 在使用 pve 的noVNC 控制台 访问 WINDOWS 虚拟机时 VM 会出现num lock 状态不同步的情况 主要是由于WINDOWS 笔者这里是 SERVER2022 启动后默认关闭了 num lock 而 pve的虚拟
  • Scala中的抽象类

    1 先看下 类的层次结构 类层次结构 也称为类分类法 是一组相关的类 它们通过继承连接起来做类似的事情 层次结构的顶部可以是一个基类 它下面的所有其他类都是从中派生出来的 或者层次结构可以有多个基类 这些基类的功能稍后会在一个或多个派生类中
  • 论文阅读-Multi-attentional Deepfake Detection

    一 论文信息 题目 Multi attentional Deepfake Detection 作者团队 会议 CVPR 2021 二 背景与创新 背景 之前大多数方法将deepfake检测模型作为一个普通的二分类问题 即首先使用骨干网络提取
  • Redis面试题

    1 基本概念 1 1 常见考点 1 Redis 为何这么快 1 基于内存 2 单线程减少上下文切换 同时保证原子性 3 IO多路复用 4 高级数据结构 如 SDS Hash以及跳表等 2 为何使用单线程 因为 Redis 是基于内存的操作
  • esp32 系列芯片分类

    模组 内置芯片 Flash PSRAM 模组尺寸 mm ESP32 WROVER PCB ESP32 D0WDQ6 4M 8M 18 00 0 10 x 31 40 0 10 x 3 30 0 10 ESP32 WROVER IPEX ES
  • 微信公众号一些错误的原因错误代码41001

    微信公众号一些错误的原因错误代码41001 错误代码41001 缺少access token 碰到这种错误 请检查自己的appid和appsecret posted on 2017 05 08 18 02 baker95935 阅读 评论
  • git如何上传所有的新文件

    目的描述 新建的git项目 项目中有许多要从本地上传到git仓库的新文件 如果用git a filename的方法一个一个的添加 太费事费力 需要有命令添加所有改动 步骤 进入项目文件夹 在其中使用git bash 1 使用git clon
  • MySQL和MongoDB那些事

    什么是 MySQL 和 MongoDB MySQL 和 MongoDB 是两个可用于存储和管理数据的数据库管理系统 MySQL 是一个关系数据库系统 以结构化表格格式存储数据 相比之下 MongoDB 以更灵活的格式将数据存储为 JSON
  • VC++ CSWDirectoryListCtrl磁盘文件列表

    效果图 头文件定义 CSWDirectoryListCtrl h pragma once include afxwin h include
  • leetcode 3. 最长不含重复的子字符串的五种解法

    leetcode链接 最长不含重复的子字符串 题目描述 给定一个字符串 s 请你找出其中不含有重复字符的 最长子串 的长度 示例 1 输入 s abcabcbb 输出 3 解释 因为无重复字符的最长子串是 abc 所以其长度为 3 示例 2