leetcode3. Longest Substring Without Repeating Characters(最长不重复子串)

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: “abcabcbb”
Output: 3
Explanation: The answer is “abc”, with the length of 3.

默认第一思路: 这个思路是我做的时候会第一想到的思路,所以先不看题解。
为了找到最长不重复子串,重点就是在于处理两个相同的字符不能在同一个区间里面,所以需要用一个hash来保证最快找到上一个相同的字符的位置在哪。可以用dp表示到这个字符的最大不重复子串,也就是动态规划,小问题就是小字符串长度,dp(1)=1, dp(2)就需要看是否之前已经存在,如果已经存在了,就要判断是到上一个的位置长度长还是直接在当前dp[i-1] 的子串+1 长,找到最小的哪个就是最有效。

code

class Solution {
public:
    //用u_map记录每个字符的pos,然后遍历,用当前pos-(-1)/上一个出现的地方
   
    int lengthOfLongestSubstring(string s) {
        if(s.size()==0)
            return 0;
        unordered_map<char,int> imap;
        int len=1;
       // vector<int> dp(s.size());
        //dp[0]=1;        //第一个字符需要设置进入imap中
        int pre=1,cur=0;
        imap[s[0]]=0;       //否则第一个字符在这之中出现是在后面第二个!并且1个字符结果是0
        for(int i=1;i<s.size();i++){
            if( imap.find(s[i])==imap.end()){
                //dp[i]=dp[i-1]+1;
                cur=pre+1;
                imap[s[i]]=i;
                pre=cur;
            }
            else{
               // dp[i]=min(i-imap[s[i]], dp[i-1]+1);     //两者相比取较小值
                cur=min(i-imap[s[i]],pre+1 );   //和前一个相比,是有你没我,有我没你
                imap[s[i]]=i;   //更新位置
                pre=cur;
                
            }
            len=max(cur,len);
        }
        return len;
    }
};

思路二:
因为anscii一共可表示256的字符(因为char最大256),所以不需要map了,所以设置数组dict(256,-1)然后开始遍历。如果找到了已经出现的,start位置改变,否则就是当前i-start
//为什么不算从当前到上一个相同的位置之间的长度,因为前一个数已经计算过了!

优化代码:

class Solution {
public:
    //用u_map记录每个字符的pos,然后遍历,用当前pos-(-1)/上一个出现的地方
   
    int lengthOfLongestSubstring(string s) {
       if(s.empty())
           return 0;
        vector<int> dict(256,-1);
        int maxlen=0, start=-1;
        for(int i=0;i<s.size();i++){
            if(dict[s[i]] >start )  //说明这个字符出现过了,上一个位置在dict[s[i]]
                start=dict[s[i]];
            dict[s[i]]=i;
            maxlen=max(maxlen, i-start);    //为什么不算从当前到上一个相同的位置之间的长度,因为前一个数已经计算过了!
        }
        return maxlen;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值