Lintcode 581 · Die längste sich wiederholende Teilsequenz [mittlere VIP-dynamische Programmierung/Rekursion]

Thema

https://www.lintcode.com/problem/581

给出一个字符串,找到最长的重复子序列的长度,并且这两个子序列不能在相同位置有同一元素。
比如:在两个子序列中的第i个元素不能在原来的字符串中有相同的下标。



样例1:

输入:"aab"
输出:1
解释:
两个子序列是a(第一个)和a(第二个)。
请注意,b不能被视为子序列的一部分,因为它在两者中都是相同的索引。2:

输入:"abc"
输出:0
解释:
没有重复的序列3:

输入:"aabb"
输出:2
解释:
有两个相同的子序列"ab". 其中第一个子序列是s[0] + s[2], 第二个子序列是s[1]+s[3], 所以重复子序列的长度为2.

Ideen

Ähnlich wie bei der Frage „Längste gemeinsame Teilfolge“. Diese Antwort umfasst sowohl die rekursive Version als auch die dynamische Programmierversion.
Andere im Internet gefundene Antworten enthalten nur dynamische Programmierversionen, die für Anfänger überhaupt nicht verständlich sind.

Antwort

public class Solution {
    
    
    /**
     * @param str: a string
     * @return: the length of the longest repeating subsequence
     */
    public int longestRepeatingSubsequence(String str) {
    
    
       if (str == null || str.length() == 0) return 0;
        //  return f1(str); //递归+缓存版本
        return dp(str.toCharArray()); //动态规划版本
    }


    public static int dp(char[] strs) {
    
    
        int n = strs.length;
        int[][] dp = new int[n + 1][n + 1];

        //填充第一行
        for (int j = 1; j < n; j++) {
    
    
            dp[0][j] = strs[0] == strs[j] ? 1 : dp[0][j - 1];
        }

        //填充第一列
        for (int i = 1; i < n; i++) {
    
    
            dp[i][0] = strs[i] == strs[0] ? 1 : dp[i - 1][0];
        }

        for (int i = 1; i < n; i++) {
    
    
            for (int j = 1; j < n; j++) {
    
    
                int p1 = dp[i - 1][j];
                int p2 = dp[i][j - 1];
                int p3 = 0;
                p3 += i != j && strs[i] == strs[j] ? (1 + dp[i - 1][j - 1]) : 0;
                dp[i][j] = Math.max(p1, Math.max(p2, p3));
            }
        }

        return dp[n - 1][n - 1];
    }

    public static int f1(String str) {
    
    
        char[] strs = str.toCharArray();
        int n = str.length();
        Integer[][] dp = new Integer[n + 1][n + 1];
        return dfs(n - 1, n - 1, strs, dp);
    }

    public static int dfs(int i, int j, char[] strs, Integer[][] dp) {
    
    
        if (i >= 0 && j >= 0 && dp[i][j] != null) return dp[i][j];
        if (i == 0 && j == 0) {
    
    
            dp[i][j] = 0;
            return 0;
        } else if (i == 0) {
    
    
            if (strs[i] == strs[j]) {
    
    
                dp[i][j] = 1;
                return 1;

            } else {
    
    
                return dfs(i, j - 1, strs, dp);
            }
        } else if (j == 0) {
    
    
            if (strs[i] == strs[j]) {
    
    
                dp[i][j] = 1;
                return 1;
            } else {
    
    
                return dfs(i - 1, j, strs, dp);
            }
        } else {
    
    
            int p1 = dfs(i - 1, j, strs, dp);
            int p2 = dfs(i, j - 1, strs, dp);

            int p3 = 0;
            p3 += i != j && strs[i] == strs[j] ? 1 + dfs(i - 1, j - 1, strs, dp) : 0;

            int ans = Math.max(p1, Math.max(p2, p3));

            dp[i][j] = ans;
            return ans;
        }
    }

}

Lokales Testbeispiel

public class LC581 {
    
    


    public static int longestRepeatingSubsequence(String str) {
    
    
        if (str == null || str.length() == 0) return 0;
        //  return f1(str); //递归+缓存版本
        return dp(str.toCharArray()); //动态规划版本
    }


    public static int dp(char[] strs) {
    
    
        int n = strs.length;
        int[][] dp = new int[n + 1][n + 1];

        //填充第一行
        for (int j = 1; j < n; j++) {
    
    
            dp[0][j] = strs[0] == strs[j] ? 1 : dp[0][j - 1];
        }

        //填充第一列
        for (int i = 1; i < n; i++) {
    
    
            dp[i][0] = strs[i] == strs[0] ? 1 : dp[i - 1][0];
        }

        for (int i = 1; i < n; i++) {
    
    
            for (int j = 1; j < n; j++) {
    
    
                int p1 = dp[i - 1][j];
                int p2 = dp[i][j - 1];
                int p3 = 0;
                p3 += i != j && strs[i] == strs[j] ? (1 + dp[i - 1][j - 1]) : 0;
                dp[i][j] = Math.max(p1, Math.max(p2, p3));
            }
        }

        return dp[n - 1][n - 1];
    }

    public static int f1(String str) {
    
    
        char[] strs = str.toCharArray();
        int n = str.length();
        Integer[][] dp = new Integer[n + 1][n + 1];
        return dfs(n - 1, n - 1, strs, dp);
    }

    public static int dfs(int i, int j, char[] strs, Integer[][] dp) {
    
    
        if (i >= 0 && j >= 0 && dp[i][j] != null) return dp[i][j];
        if (i == 0 && j == 0) {
    
    
            dp[i][j] = 0;
            return 0;
        } else if (i == 0) {
    
    
            if (strs[i] == strs[j]) {
    
    
                dp[i][j] = 1;
                return 1;

            } else {
    
    
                return dfs(i, j - 1, strs, dp);
            }
        } else if (j == 0) {
    
    
            if (strs[i] == strs[j]) {
    
    
                dp[i][j] = 1;
                return 1;
            } else {
    
    
                return dfs(i - 1, j, strs, dp);
            }
        } else {
    
    
            int p1 = dfs(i - 1, j, strs, dp);
            int p2 = dfs(i, j - 1, strs, dp);

            int p3 = 0;
            p3 += i != j && strs[i] == strs[j] ? 1 + dfs(i - 1, j - 1, strs, dp) : 0;

            int ans = Math.max(p1, Math.max(p2, p3));

            dp[i][j] = ans;
            return ans;
        }
    }


    public static void main(String[] args) {
    
    
        System.out.println(longestRepeatingSubsequence("aab")); //1
        System.out.println(longestRepeatingSubsequence("aabb")); //2
        System.out.println(longestRepeatingSubsequence("abc")); //0
        System.out.println(longestRepeatingSubsequence("aaadaaaaaaaaaaabbbbbbbb" +
                "bbbbbbbbbbbmmmmmmmmmmmmmmmdkkkkklkklkldd" +
                "ddddddddddddddddddddddddddddssssssssss" +
                "ssssssssbb"));//100
    }
}

Guess you like

Origin blog.csdn.net/weixin_37991016/article/details/132865486