Hot100-Day09-T2无重复字符的最长字串

3 阅读2分钟

Day09[26/3/9]T2无重复字符的最长字串

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

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。注意 "bca""cab" 也是正确答案。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

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

提示:

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

解题思路

这里使用大名鼎鼎的滑动窗口算法。

首先维护好两个变量 leftright分别记录你现在的字串的左右边界。

然后考虑,你要从头到尾搜索,那么你就让这两个变量一开始为 0,然后右边界每一次递增 1 就好。在递增之后,你需要检查递增引入的这个新字符(也就是 s[right])会不会和窗口内的已有字符有重复,如果有重复,那你就把 left右移,使得刚好不重复,所以也就是让 left指向重复字符的后一个字符就行了。

最后记得,需要一个全局的变量记录全局过程中,这个最长子字符串有多长。

Code

#include <iostream>
#include <string>

using namespace std;

class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        int maxLength = 0;
        int left = 0;
        int right = 0;

        while (right != s.size())
        {
            for (int i = left; i < right; i++)
            {
                if (s[right] == s[i])
                {
                    left = i + 1;
                    break;
                }
            }

            if (maxLength < right + 1 - left)
            {
                maxLength = right + 1 - left;
            }

            right++;
        }

        return maxLength;
    }
};

auto main() -> int
{
    // std::string s = "abcabcbb";
    std::string s = "bbbbb";

    Solution sol;

    cout << "s: \t" << s << endl
         << "Length:\t" << sol.lengthOfLongestSubstring(s) << endl;
}