【LeetCode热题100】【滑动窗口】无重复字符的最长子串

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

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

题解

首先是我自己的思路,因为比较直接所以比较暴力

遍历字符串的每个字符,按照当前无重复字符的字串的长度提取子串,在字串中寻找是否有相同的字符,如果有相同的字符,更新子串的起始字符为相同字符的后面一个字符,同时更新当前字串的长度

这里寻找相同字符的位置比较讲究,首先找出相同字符在子串的位置,再加上字串在字符串中的位置,之所以用rfind倒着查找是避免存在多个相同字串返回第一个字串的结果,用rfind加上i的位置可以返回正确位置的子串的位置

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s=="")
            return 0;
        int longest=1,begin=0,longer=1;
        string son;
        for(int i=1;i<s.size();i++){
            son=s.substr(begin,longer);
            int newBegin=son.find(s[i]);
            if(newBegin!=string::npos){
                newBegin=s.rfind(son,i-1)+newBegin;
                longer=i-newBegin;
                begin=newBegin+1;
            }else{
                longer++;
                longest=longest<longer?longer:longest;
            }
        }
        return longest;
    }
};

下面这个是更加简洁和优化的写法,思路还是一样的

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int longest=0,begin=0,end=0;
        while(end<s.size()){
            for(int i=begin;i<end;i++){ //子串重复判断
                if(s[i]==s[end]){
                    begin=i+1; //更新子串起始位置
                    break;
                }
            }
            longest=max(longest,end-begin+1);
            end++;
        }
        return longest;
    }
};

 

猜你喜欢

转载自blog.csdn.net/weixin_62264287/article/details/134837896