学习记录-LeetCode-剑指offer48:最长不含重复字符的子字符串

题目描述:请从字符串中找出一个最长的不含重复字符的子字符串,计算该字符串的长度。

示例:输入:“abcabcbb”   输出:3

分析:此题属于变种动态规划(个人理解)

首先找到初始值,对于第一个字符,只要s不为空,字符最大长度max为1

随后寻找dp[n]和dp[n-1]的关系:

        分为以下种情况:

                1.如果该字符没有出现过,那么temp=temp+1,并需要记录一下该字符出现的索引

                2.如果该字符出现过再分为两种情况:

                        (1)一般情况,即该字符两次出现的中间,没有出现重复字符的情况下,此时的最大长度为该字符当前位置-该字符上次出现位置。并且更新该字符出现的位置。

                        (2)像“abba”这种情况,在a两次出现的中间,有重复字符,temp=temp+1,因为此时temp计算的长度已经不是从上一次出现a字符开始算了,而是上一次没有出现重复字符开始算,也就是第二个b的位置开始计算。

ps:temp只记录从当前字符往前的不重复字符串的长度。

如何判断某个字符两次出现的中间部分有没有重复的数字呢?如果出现重复字符,temp的长度不再是这两个重复字符两次出现的位置差,而是从不重复字符开始到当前字符的长度,所以,

temp<该字符两次出现的位置差,可以用来判断是否出现过重复字符。

我们用HashMap<Character,Integer>来记录每个字符上一次出现的位置,用temp和max分别记录临时的最大值和全局的最大。

class Solution{
    public int lengthOfLongestSubstring(String s){
        Map<Character,Integer> dic = new HashMap<>();
        int temp=0,max=0;
        for(int j=0;j<s.length();j++){
            if(dic.containsKey(s.charAt(j))){
                int i = dic.get(s.charAt(j));
                dic.put(s.charAt(j),j);
                if(temp<j-i){
                    temp+=1;
                }else{
                    temp=j-i;
                }
            }
            else{
                dic.put(s.charAt(j),j);
                temp=temp+1;
            }
            max=Math.max(temp,max);
        }
        return max;
    }
}

后面再想想,只要把get()换成getOrDefault()方法,若第一次出现则返回-1,就可以合并第一种情况和第2.2种情况。再用上正则表达式,可以使代码精简不少 (虽然是抄大佬的解法)

Class Solution{
    public int lengthOfLongestSubstring(String s){
        Map<Character,Interger> dic=new HashMap<>();
        int temp=0,max=0;
        for(int j=0;i<=s.length.j++){
            int i=dic.getOrDefault(s.charAt(j),-1);
            dic.put(s.charAt(j),j);
            temp=temp<j-i?temp+1:j-1;
            max=Math.max(temp,max);
        }
        return max;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值