471. Encode String with Shortest Length

题目链接:https://leetcode.com/problems...

这题还是有点难想的,一开始dp的思路想的还不对,参考这个博客的解释:http://www.cnblogs.com/grandy...

dpi表示s[i, j]最短的压缩结果,subproblem里面枚举切分点k,分别得到dpi和dpk+1求和,找到长度最短的。

这道题关键是找sub = abcabc这种可压缩的情况,其中sub = s[i,j]。方法比较巧妙,用sub+sub = abcabcabcabc,找第二个s在s+s里出现的位置,如果不是len(sub),则说明sub有重复,那么就要压缩这个sub,重复次数是len(sub) / indexOf(sub, 1),重复的string用的是之前压缩过的dpi,index = indexOf(sub, 1)。

public class Solution {
    public String encode(String s) {
        int n = s.length();
        String[][] dp = new String[n][n];
        for(int i = 0; i < n; i++) dp[i][i] = "" + s.charAt(i);
        // j - i
        for(int len = 1; len < n; len++) {
            for(int i = 0; i + len < n; i++) {
                int j = i + len;
                // enumerate seperate k
                for(int k = i; k < j; k++) {
                    int left = dp[i][k].length();
                    int right = dp[k+1][j].length();
                    // update shortest encoded string within (i, j)
                    if(dp[i][j] == null || left + right < dp[i][j].length()) {
                        dp[i][j] = dp[i][k] + dp[k+1][j];
                    }
                }
                // update string within (i, j), encode abcabc
                String sub = s.substring(i, j + 1);
                int index = (sub + sub).indexOf(sub, 1);
                if(index < sub.length()) {
                    sub = (sub.length() / index) + "[" + dp[i][i+index-1] + "]";
                }
                if(dp[i][j] == null || dp[i][j].length() > sub.length()) {
                    dp[i][j] = sub;
                }
            }
        }
        
        return dp[0][n-1];
    }
}

lulouch13
13 声望6 粉丝

下一篇 »
475. Heaters