无重复字符的最长子串 -力扣中等

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

示例 1:

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

示例 2:

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

示例 3:

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

请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

提示:

0 < = s . l e n g t h < = 5 ∗ 1 0 4 0 <= s.length <= 5 * 10^4 0<=s.length<=5104
s 由英文字母、数字、符号和空格组成

解题思路

本题可以使用动态规划的思想,定义数组 dp[N]dp[i]代表以第i个字符s[i]作为结束的最大子串长度。那么对于第i+1个字符,会出现两种情况:
\qquad - s[i+1]没有出现在以s[i]结束的最大子串里面
\qquad - s[i+1]出现在以s[i]结束的最大子串里面
\qquad 对于第一种情况,直接将s[i+1]加入以s[i]为结束的最大子串即可。
\qquad 对于第二种情况,首先需要找到s[i+1]上一次出现的位置preprei+1的长度即为以s[i+1]结束的子串的最大长度。
怎么找到s[i+1]上一次出现的位置呢,我们可以使用C++的标准库map,更新map[s[i]]=i即可。

解题代码

#include<iostream>
#include<string>
#include<map>
using namespace std;
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if (s.length()==0) return 0;
        map<char,int>counter;
        int dp[int(s.length())+1];
        for (int i=0;i<s.length();i++){
            dp[i]=1;
        }
        counter[s[0]]=0;
        int max_len = 1;
        for(int i=1;i<s.length();i++){
            if(counter.find(s[i])==counter.end()){
                dp[i]=dp[i-1]+1;
            }
            else{
                int pre = counter[s[i]];
                if(pre<i-1-dp[i-1]+1){
                    dp[i]=dp[i-1]+1;
                }
                else{
                    dp[i]=max(dp[i],i-pre);
                }

            }
            counter[s[i]]=i;
            max_len=max(max_len,dp[i]);
        }
        //for (int i=0;i<s.length();i++){
        //    cout<<dp[i]<<" ";
        //}cout<<endl;
        return max_len;

    }
};

int main(){
    string s="pwwkew";
    map<char,int>counter1;

    for (int i=0;i<s.length();i++){
        counter1[s[i]]+=1;
    }
    Solution so = Solution();
    int res = so.lengthOfLongestSubstring(s);
    cout<<res<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力搬砖的小王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值