zoukankan      html  css  js  c++  java
  • LeetCode 3. Longest Substring Without Repeating Characters

    问题链接

    LeetCode 3

    题目解析

    求字符串的最长无重复子串

    解题思路

    第一个问题是子串,注意是连续的。

    建立一个符号哈希数组 (in[256]),代表该符号时候出现过,256大小是因为ASCII表共能表示256个字符。初始化为0,代表未出现,当 (in[i] > 0) 时,表示该字符最近出现的索引位置+1。

    定义变量(res):记录最长无重复子串长度;(left)包含当前字符的最长无重复子串的起始位置。遍历字符串,遇到未出现的字符((in[s[i]] == 0))时,更新 (res);注意另一种情况,当哈希表中的值小于 (left),原因是出现过重复的字符,导致 (left) 的位置更新了(变大),如果又遇到了新的字符或者虽然重复,但重复位置在 (left) 之前,也需要更新 (res)。否则的话,就要更新 (left) 的位置为 (in[s[i]])

    (left) 更新问题:注意理解更新 (left) 的条件,一方面理解:无法更新 (res),就要更新 (left),二者是对立的;另一方面,直接理解更新条件:(in[s[i]] > 0 && in[s[i]] >= left)。在当前字符重复的情况下,且重复位置在 (left) 的右边时,更新 (left)

    注意每次都需要更新 (in[s[i]] = i+1),目的是下次再遇到此字符时,直接将 (left) 赋值为 (in[s[i]]),保证无重复。

    参考代码

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            vector<int> in(256, 0);
            int res = 0, left = 0;
            for (int i = 0; i < s.size(); i++) {
                if (in[s[i]] == 0 || in[s[i]] < left) {
                    res = max(res, i-left+1);
                }
                else
                    left = in[s[i]];
                in[s[i]] = i+1;
            }
            return res;
        }
    };
    

    思路一样,有一种更精简的写法。(res)(left) 的定义不变,(in[s[i]]) 的值稍微变化,变为字符最近出现的索引位置,没有+1。

    先更新 (left),再更新 (in[s[i]]),最后更新 (res),妙不可言~

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            vector<int> in(256, -1);
            int res = 0, left = -1;
            for (int i = 0; i < s.size(); ++i) {
                left = max(left, in[s[i]]);
                in[s[i]] = i;
                res = max(res, i - left);
            }
            return res;
        }
    };
    

    解法二:set

    运用集合(set),其特点是不包含重复元素。思路其实还是没有变,遍历字符串,把未出现过的字符都放入set中,更新结果res;如果遇到重复字符,则从左边开始删字符,直到删到集合中没有重复的字符停止。

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            set<char> t;
            int res = 0, left = 0, right = 0;
            while (right < s.size()) {
                if (t.find(s[right]) == t.end()) {
                    t.insert(s[right++]);
                    res = max(res, (int)t.size());
                }  else {
                    t.erase(s[left++]);
                }
            }
            return res;
        }
    };
    

    LeetCode All in One题解汇总(持续更新中...)

    本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


  • 相关阅读:
    怎么说???
    再给自己一点鼓励
    还是不要看新闻的好
    系统架构师
    朋友
    未来的路
    I now have a dream
    纪念死去的手机
    全局规划
    终于要上战场了!
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8535430.html
Copyright © 2011-2022 走看看