【(非)连续最长公共子序列模板】

1.连续最长公共子序列

t718 最长重复子数组 = 牛客题霸NC127 最长公共子串(求连续最长公共子序列的具体结果 )

**1.1 t718 最长重复子数组

    public int findLength(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int len2 = nums2.length;
        int[][] dp = new int[len1+1][len2+1];
        
        int res = 0;//连续最长公共子序列的长度

        for(int i = 1; i <= len1; i++){
            for(int j = 1; j <= len2; j++){
                if(nums1[i-1] == nums2[j-1])
                    dp[i][j] = dp[i-1][j-1] + 1;
                // else    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);本题是求 连续 最长公共子序列,不必加这行
                
                res = Math.max(res,dp[i][j]);
            }
        }

        return res;
    }

**1.2 牛客题霸NC127 最长公共子串(求连续最长公共子序列的具体结果 )

    public int findLength(int[] nums1, int[] nums2) {
        //如果想求出具体的连续最长公共子序列,通过末尾下标end和长度res计算截取
        int end = 0;//连续最长公共子序列在nums1的末尾下标,有了末尾下标和长度res,就可以截取出来了
        
        int len1 = nums1.length;
        int len2 = nums2.length;
        int[][] dp = new int[len1+1][len2+1];
        
        int res = 0;//连续最长公共子序列的长度

        for(int i = 1; i <= len1; i++){
            for(int j = 1; j <= len2; j++){
                if(nums1[i-1] == nums2[j-1])
                    dp[i][j] = dp[i-1][j-1] + 1;
                
                // if(res < dp[i][j])  end = i-1;//如果想求出具体的连续最长公共子序列,通过末尾下标end和长度res计算截取
                
                res = Math.max(res, dp[i][j]);
            }
        }

        // System.out.println(Arrays.copyOfRange(nums1, end-res+1, end+1));//截取的结果

        return res;
    }

2.可不连续最长公共子序列

t1143 最长公共子序列=t1035 不相交的线;
稍微绕个弯 t392 判断子序列=t583 两个字符串的删除操作;
2.1 可不连续最长公共子序列
2.1.1 t1143 最长公共子序列=t1035 不相交的线;

    public int longestCommonSubsequence(String text1, String text2) {
        int len1 = text1.length();
        int len2 = text2.length();
        int[][] dp = new int[len1+1][len2+1];
        
        int res = 0;//可不连续公共子序列的长度

        for(int i = 1; i <= len1; i++){
            for(int j = 1; j <= len2; j++){
                if(text1.charAt(i-1) == text2.charAt(j-1))    dp[i][j] = dp[i-1][j-1] + 1;
                else    dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]);//不要求必须是连续序列就加上,要求必须连续序列t718就不用加
               
                res = Math.max(res,dp[i][j]);
            }
        }

        return res;
    }

2.2 可不连续最长公共子序列(绕个弯)
2.2.1 t392 判断子序列

    public boolean isSubsequence(String s, String t) {
        int len1 = s.length();
        int len2 = t.length();
        int[][] dp = new int[len1+1][len2+1];
        
        int res = 0;//可不连续公共子序列的长度

        for(int i = 1; i <= len1; i++){
            for(int j = 1; j <= len2; j++){
                if(s.charAt(i-1) == t.charAt(j-1))    dp[i][j] = dp[i-1][j-1] + 1;
                else    dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]);//不要求必须是连续序列就加上,要求必须连续序列t718就不用加
               
                res = Math.max(res,dp[i][j]);
            }
        }

        return res == len1;

    }

2.2.2 t583 两个字符串的删除操作

    public int minDistance(String word1, String word2) {
        int len1 = word1.length();
        int len2 = word2.length();
        int[][] dp = new int[len1+1][len2+1];
        
        int res = 0;//可不连续公共子序列的长度

        for(int i = 1; i <= len1; i++){
            for(int j = 1; j <= len2; j++){
                if(word1.charAt(i-1) == word2.charAt(j-1))    dp[i][j] = dp[i-1][j-1] + 1;
                else    dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]);//不要求必须是连续序列就加上,要求必须连续序列t718就不用加
               
                res = Math.max(res,dp[i][j]);
            }
        }

        return len1+len2 - 2*res;
    }

你可能感兴趣的:(刷题,Java,笔记,动态规划,算法,概率论)