每日刷题计划Day1笔记-字符串

题源:LeetCode

3.无重复字符的最长子串

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

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

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

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

示例 4:
输入: s = “”
输出: 0

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters

我的思路:1.遍历找子串 2.判断子串是否重复(暴力或者KMP)并把重复次数记录下来 3.输出重复次数最少的字串
错误点:并没有注意到题中说的是“无重复字符”的子串。

答案思路:
关键字:
重复字符->出现1次->模式识别1:一旦涉及出现次数,需要用到散列表。
构造子串,散列表存下标->识别模式2:涉及子串,考虑滑动窗口

滑动窗口

什么是滑动窗口?
其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列。

如何移动?
把队列的左边的元素移出,直到满足题目要求。
一直维持这样的队列,找出队列出现最长的长度时候,求出解。
时间复杂度:O(n)

class Solution{
   
public:
    int lengthOfLongestSubstring(string s) {
   
        //s[start,end) 前面包含 后面不包含
        int start(0), end(0), length(0), result(0);
        int sSize = int(s.size());
        while (end < sSize){
   
        //每次挪动end一个长度,可以覆盖全部子字符串
            for (int index = start; index < end; index++)//index[start,end)
                //start之前的肯定有重复字符,所以不考虑
                if (s[index] == s[end]){
   
        		//如果[start,end)中有与end重复的字符,则砍掉左边[start,index]。剩下[index+1,end)
                    start = index + 1;
                    length = end - start;//[start,end)的长度
                    break;//只可能有一个重复的字符,所以找到了

你可能感兴趣的:(LeetCode刷题,c++,LeetCode一刷,leetcode,算法,滑动窗口,PAT甲级)