516. 最长回文子序列

​ 回文:正这读和反着读的意思是一样的一段话。

第一次尝试

​ 第一次没有懂回文的意思,直接找的出现次数最多的字符。

class Solution {
    public int longestPalindromeSubseq(String s) {
        int res = 0;
        Map<Character,Integer> map = new HashMap<>();
        char[] cs = s.toCharArray();
        for(char c:cs){
            Integer in = map.get(c);
            if(in!=null){
                map.put(c,in+1);
            }else{
                map.put(c,1);
            }
        }   
        for(Integer entry:map.values()){
            res = Math.max(res,entry.intValue());
        }
        return res;
    }
}

动态规划

输入:s = "bbbab"
输出:4
可以删除某些字符
"aabaa"
输出:5

​ 比如aabaa,aba也是回文字符串,那么可以从一个字符两边开始找。

​ 再比如cbba,bb是回文字符串,最短的回文字符串长度为2,如果没有res = 1;

​ 假设这一状态转移方程

dp/[i]/[j] 表示下标范围[i,j]内的最长回文字符串长度。

当s[i] = s[j] ,dp/[i]/[j] = dp/[i+1]/[j-1] + 2

当s[i] != s[j] ,dp[i]/[j] = max(dp[i+1]/[j],dp[i]/[j-1])

最终res = dp[0]/[n-1];

class Solution {
    public int longestPalindromeSubseq(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        for (int i = n - 1; i >= 0; i--) {
            dp[i][i] = 1;
            char c1 = s.charAt(i);
            for (int j = i + 1; j < n; j++) {
                char c2 = s.charAt(j);
                if (c1 == c2) {
                    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][n - 1];
    }
}

583. 两个字符串的删除操作

找最大的公共子序列

class Solution {
    /**
    找最大子序列的问题 

    aaaabbbcc
    abbcc

    动态规划

    
     */
    public int minDistance(String word1, String word2) {
        int len = word1.length();

        int len2 = word2.length();

        int[][] dp = new int[len+1][len2+1];

        for(int i = 1;i<=len;i++){
            char c1 = word1.charAt(i-1);
            for(int j= 1;j<=len2;j++){
                char c2 = word2.charAt(j-1);


                if(c1==c2){
                    dp[i][j] = dp[i-1][j-1]+1;
                }else{
                    dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]);
                }
            }
        }
        return len2+len-2*dp[len][len2];



    }
}
  1. 最长定差子序列
    https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/

动态规划


class Solution {
    /**
    HashMap
     */
    public int longestSubsequence(int[] arr, int difference) {
        int res =0;
        Map<Integer,Integer> dp = new HashMap<>();
        for(int n:arr){
            dp.put(n,dp.getOrDefault(n-difference,0)+1);

            res = Math.max(res,dp.get(n));
        }

        return res;

    }
}
  1. 300.最长递增子序列

最长递增子序列可以使用动态规划的思想 dp[0] 在数组位置0 他的最长递增子序列为1;

dp[0] = 1;

  1. 674.最长连续递增序列
  2. 718.最长重复子数组
  3. 1143.最长公共子序列
  4. 1035.不相交的线
  5. 53.最大子序和
  6. 392.判断子序列
  7. 115.不同的子序列
  8. 583.两个字符串的删除操作
  9. 72.编辑距离
  10. 为了绝杀编辑距离,我做了三步铺垫,你都知道么?
  11. 647.回文子串
  12. 516.最长回文子序列
  13. 动态规划总结篇