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

题目:

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

 

示例 1:

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

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

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

 

解答:

DP

状态定义:dp[j]表示以s.charAt(j)为结尾的子字符串的“最长不含重复字符的字符串”的长度

转移方程: 固定右边界 j,设字符 s[j]左边距离最近的相同字符为s[i] ,即s[i] == s[j]

s[sssss

获得s[i]的方法有多种:

1,用哈希表,用此法,时间复杂度为o(n)

2,线性遍历,往s[j]左边找第一个相同的字符即可,用此法,时间复杂度为o(n^2)

dp[j] = dp[j-1] + 1(dp[j-1]<j-i)

dp[i] = j-i  (dp[j-1]>=j-i)

 

代码:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        if(n == 0){
            return 0;
        }
        int[] dp = new int[n];
        dp[0] = 1;
        Map<Character,Integer> map = new HashMap<>();
        map.put(s.charAt(0),0);

        int res = dp[0];
        for(int j = 1;j<n;j++){
            int i = map.getOrDefault(s.charAt(j),-1);
            map.put(s.charAt(j),j);
            if(dp[j-1]<j-i){
                dp[j] = dp[j-1]+1;
            }else{
                dp[j] = j-i;
            }
            res = Math.max(dp[j],res);
        }

        return res;
    }
}

 

代码优化:

优化空间复杂度

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        if(n == 0){
            return 0;
        }
        //int[] dp = new int[n];
        int pre = 1,p;
        Map<Character,Integer> map = new HashMap<>();
        map.put(s.charAt(0),0);

        int res = 1;
        for(int j = 1;j<n;j++){
            int i = map.getOrDefault(s.charAt(j),-1);
            map.put(s.charAt(j),j);
            if(pre<j-i){
                p = pre+1;
            }else{
                p = j-i;
            }
            
            pre = p;
            
            res = Math.max(p,res);
            
        }

        return res;
    }
}

 

 

 

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
 
示例 1:
输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。示例 2:
输入: "bbbbb"输出: 1解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。示例 3:
输入: "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

posted @ 2020-12-10 21:36  3KBLACK  阅读(99)  评论(0)    收藏  举报