剑指 Offer 48. 最长不含重复字符的子字符串

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

分析: 我们可以这样定义dp数组:dp[i] 以第i个字符结尾的最长的不包含重复字符的子字符串。

然后我们可以用Hash表记录下字符数组每个字符的最近一次数组下标。如果之前没有出现过就赋值为-1;

然后我们分析下选择:
①如果第i个字符没有出现过(-1)那么dp[i]=dp[i-1]+1;
②如果第i个字符之前出现过,且之前的下标为t;

  • i-t >dp[i-1]: dp[i]=dp[i-1]+1;
  • i-t<=dp[i-1]: dp[i]=i-t;

然后再遍历dp数组,选择最大的那一个;

class Solution {
    public int lengthOfLongestSubstring(String s) {

        if(s==null||s.length()==0){
            return 0;
        }
        Map<Character,Integer> map=new HashMap<>();
        int n=s.length();
        int res=Integer.MIN_VALUE;
        char[] charArray=s.toCharArray();
        // 定义dp[j]为:以第j个字符为结尾的不包含重复字符的子字符串的最大长度
        int dp[]=new int [n];
        map.put(charArray[0],0);
        dp[0]=1;
        for(int i=1;i<n;i++){
            int t=map.getOrDefault(charArray[i],-1);
            map.put(charArray[i],i);
            if(t==-1){
                dp[i]=dp[i-1]+1;
            }else{
                dp[i]=(i-t)>dp[i-1]?dp[i-1]+1:i-t;
            }
        }
        for(int i=0;i<n;i++){
            res=Math.max(res,dp[i]);
        }
        return  res;



    }
}
上一篇:Leetcode 48 旋转图像


下一篇:Ubuntu等Linux系统清除DNS缓存的方法