【动态规划】——无重复字符的最长子串

998 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

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

思路

1.一个int[]数组reocord记录字符的位置,这是比较常用的一种解题方法

2.初始时将record所有值变为-1方便后面比较

3.遍历s的字符数组,分为两种情况
      I. record[chars[i]] == -1//表示这个字符前面没有出现过
              只需要把i位置的字符加到dp[i-1]的情况上面


      II. record[chars[i-1] != -1//表示前面这个字符出现过
               那么需要看在dp[i-1]的时候里面时候是否有chars[i],
               可以用i-1-dp[i-1]>=record[chars[i]]
               //i-1位置 前前移动dp[i-1]个位置如果此时>=record[chars[i]]所在的位置说明在dp[i-1]里面没有包括chars[i]

代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) return 0;

        char[] chars = s.toCharArray();
        int[] record = new int[256];
        int[] dp = new int[chars.length];
        int max = 1;
        Arrays.fill(record, -1);
        dp[0] = 1; //表示以0位置上面字符结尾的字符串
        record[chars[0]] = 0;
        for (int i = 1; i < chars.length; i++) {
            if (record[chars[i]] != -1) { //表示这个字符前面出现过
                //看这个字符有没有包括在范围里面   0123456
                if (i - record[chars[i]] > dp[i - 1]) { //说明不在范围里面
                    dp[i] = dp[i - 1] + 1;
                    max = Math.max(dp[i], max);
                    record[chars[i]] = i;

                } else {  //说明在范围里面
                    dp[i] = i - record[chars[i]];
                    max = Math.max(dp[i], max);
                    record[chars[i]] = i;
                }
            } else { //这个字符前面没有出现过,那么直接添加就可以
                dp[i] = dp[i - 1] + 1;
                max = Math.max(dp[i], max);
                record[chars[i]] = i;
            }
        }
        return max;
    }
}