美文网首页
516. 最长回文子序列

516. 最长回文子序列

作者: 漫行者_ | 来源:发表于2021-08-17 17:31 被阅读0次

516. 最长回文子序列

对于大部分子序列和子串的问题采用动态规划问题。
看到题目一开始想到的是一维数组来做dp,显然没办法做。
dp[i][j]表示i到j最大的子序列的最长回文数。

                if(s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i+1][j-1] + 2;
                } else {
                    dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
                }

要根据转移方程来写循环,观察到i要用到更大的i做基础。因此从s.length开始,然后减减。
观察到j要用到更小的,所以++,因为j要比i大,所以从i开始。
答案如下:

    public int longestPalindromeSubseq(String s) {
        int dp[][] = new int[s.length()][s.length()];
        for (int i = s.length()-1; i >= 0; i--) {
            for (int j = i; j < s.length(); j++) {
                if(j == i) {
                    dp[i][j] = 1;
                } else if(j == i+1) {
                    if (s.charAt(i) == s.charAt(j)) {
                        dp[i][j] = 2;
                    } else {
                        dp[i][j] = 1;
                    }
                } else if(s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i+1][j-1] + 2;
                } else {
                    dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
                }
            }
        }

        return dp[0][s.length()-1];
    }

今天还做了一道简单题如下:

551. 学生出勤记录 I

显然可以通过动态规划来做:

    public boolean checkRecord(String s) {
        int n = 0;
        int m = 0;
        if(s.charAt(0) == 'L') n = 1;
        if(s.charAt(0) == 'A') m++;
        for(int i=1; i<s.length(); i++) {
            if(s.charAt(i) == 'A') {
                m++; 
            }
            if(s.charAt(i) == 'L') {
                n++;
                if(n == 3) {
                    return false;
                }
            } else {
                n = 0;
            }
        }
        if(m>=2) {
            return false;
        }
        return true;
    }

相关文章

网友评论

      本文标题:516. 最长回文子序列

      本文链接:https://www.haomeiwen.com/subject/wreibltx.html