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


原文地址:https://www.cnblogs.com/AlvinZH/p/8535430.html