力扣3-无重复字符的最长子串

简介: 分享力扣上的解题记录,包含滑动窗口、哈希表、桶等方法

题目要求

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

示例一
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例二
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例三
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
  请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
  • 提示:

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

原题链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/

解题

滑动窗口

  1. 最开始的时候

    1. 创建START、END指向字符串最前端的位置
    2. 创建LENTH记录当前长度
    3. 创建RESULT记录无重复字符的最长字串长度
  2. 使用循环,向后移动END

    1. 检查END指向的新字符是否与字串内的字符重复

      • 如果重复,移动START到重复字符的下一个位置
      • 如果不重复,则不移动
    2. 重新计算LENTH=END-START+1
    3. 对比当前LENTG和已记录的RESULT,取较大值为新RESULT
分析图中过程:
  1. 上图中,左侧三步中均无重复字符

    1. START停留在原地不动,END++
  2. 右侧第一幅图中,END指向的新字符A与子串中字符A重复

    1. START移动到原子串中字符A的下一个位置,即字符B所在位置
    2. LENTH=3;
    3. RESULT=3;
  3. 右侧第二幅图中,END指向的新字符C与子串中字符C重复

    1. START移动到原子串中字符C的下一个位置,即字符A所在位置
    2. LENTH=2
    3. RESULT=3
敲代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int start(0), end(0), result(0);
        for (int index = 0; index < s.size(); index++)
        {
            end = index;
            for (int i = start; i < end; i++)
            {
                if (s[i] == s[end])
                {
                    start = i + 1;
                    //及时跳出
                    break;
                }
            }
            result = max(result, end - start + 1);
        }
        return result;
    }
};
运行结果
执行用时: 8 ms
内存消耗: 6.7 MB
image.png

哈希表

思路与滑动窗口相同,不同的是查找重复元素的方式

  • 滑动窗口是用遍历字符串的方式
  • 哈希表是用容器自带的find方法

需要注意的是:

  1. 查找到重复元素后,要将表中记录的该元素的位置修改为最新位置
  2. 由于重新确定区间后,不清楚到底少了哪些元素,所以判断重复元素时,应确保该位置在START之后
代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int start(0), end(0), result(0);
        unordered_map<char, int>mp;
        for (int i = 0; i < s.size(); i++)
        {
            end = i;
            if (mp.find(s[i]) != mp.end() && mp[s[i]] >= start)
            {
                start = mp[s[i]] + 1;
            }
            mp[s[i]] = end;
            result = max(result, end - start + 1);
        }
        return result;
    }
};
运行结果
执行用时: 20 ms
内存消耗: 8.1 MB
image.png

桶优化

判断是否出现过时,利用vector容器代替哈希表以优化时间

  • int[26]用于字母'a'-'z'或'A'-'Z'
  • int[128]用于ASCII码
  • int[256]用于扩展ASCII码

思路与前两种方法相同,不同的仍是检验重复的方法

  1. 每次移动END,都将END指向的字符转化为ASCII码对应的数字
  2. vector容器中对应的数字下标的值存储的是改数字最后出现的位置

    1. 如vec[2]=3,意思是ASCII码中值为2的字符,目前最后一次出现在字符串中的第4个字符的位置
  3. 判断END所指的字符在vector容器中存储的位置,是否大于START

    • 如果大于,则修改START,指向存储的位置的下一个位置
    • 否则,不操作START
代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int start(0), end(0), result(0);
        vector<int>v(128, -1);
        for (int i = 0; i < s.size(); i++)
        {
            end = i;
            if (v[int(s[i])] >= start)
            {
                start = v[int(s[i])] + 1;
            }
            v[int(s[i])] = end;
            result = max(result, end - start + 1);
        }
        return result;
    }
};
运行结果
执行用时:8 ms, 在所有 C++ 提交中击败了88.74%的用户
内存消耗:7.4 MB, 在所有 C++ 提交中击败了79.74%的用户
image.png

总结

力扣给这道题的分类是中等,对新手来说很难,而且还用到了两个指针,虽然上面的代码中用的是下标访问的方式,不是严格的指针,但也不容易,建议就是多看看题解,多写几遍代码,对于容器和重载的一些方法,可以随时去cplusplus网站查阅,边刷题边巩固

目录
相关文章
|
22天前
|
存储 算法
Leetcode第三题(无重复字符的最长子串)
这篇文章介绍了解决LeetCode第三题“无重复字符的最长子串”的算法,使用滑动窗口技术来找出给定字符串中最长的不含重复字符的子串,并提供了详细的代码实现和解释。
54 0
Leetcode第三题(无重复字符的最长子串)
|
3月前
|
算法
LeetCode第3题无重复字符的最长子串
该文章介绍了 LeetCode 第 3 题无重复字符的最长子串的解法,通过使用 HashSet 记录不重复的子元素,以每个字符开头遍历字符串,遇到重复字符则重新计算,最终找到最长子串,同时提到可以考虑使用 HashMap 降低复杂度。
LeetCode第3题无重复字符的最长子串
|
5月前
|
存储 算法 数据可视化
深入解析力扣161题:相隔为 1 的编辑距离(逐字符比较与动态规划详解)
深入解析力扣161题:相隔为 1 的编辑距离(逐字符比较与动态规划详解)
|
5月前
|
存储 算法 数据可视化
深入解析力扣157题:用Read4高效读取N个字符(多种解法与详细图解)
深入解析力扣157题:用Read4高效读取N个字符(多种解法与详细图解)
|
4月前
|
索引
821.字符的最短距离-力扣(LeetCode)
821.字符的最短距离-力扣(LeetCode)
31 0
|
5月前
|
存储 算法 程序员
力扣经典150题第三十一题:无重复字符的最长子串
力扣经典150题第三十一题:无重复字符的最长子串
29 0
|
5月前
【LeetCode刷题】滑动窗口思想解决问题:长度最小的子数组、无重复字符的最长子串
【LeetCode刷题】滑动窗口思想解决问题:长度最小的子数组、无重复字符的最长子串
|
5月前
|
存储 算法 数据可视化
深入解析力扣159题:至多包含两个不同字符的最长子串(滑动窗口法详细图解)
深入解析力扣159题:至多包含两个不同字符的最长子串(滑动窗口法详细图解)
|
5月前
|
存储 算法 数据挖掘
LeetCode 第三题:无重复字符的最长子串 详解 【3/1000】
LeetCode 第三题:无重复字符的最长子串 详解 【3/1000】
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行