洛谷P1439 最长公共子序列(java)

链接:https://www.luogu.com.cn/problem/P1439

思路参考:https://www.luogu.com.cn/blog/pks-LOVING/junior-dynamic-programming-dong-tai-gui-hua-chu-bu-ge-zhong-zi-xu-lie

题目描述:

给出 1,2,...... ,n  的两个全排列P1和P2,求它们的最长公共子序列。

AC代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] a1 = new int[n+1];
        int[] a2 = new int[n+1];
        int[] map = new int[n+1];
        int[] f = new int[n+1];
        int len = 0;
        
        //序列1
        for (int i = 1; i <= n; i++) {
            a1[i] = in.nextInt();
            map[a1[i]] = i;
        }
        //序列2
        for (int i = 1; i <= n; i++) {
            a2[i] = in.nextInt();
            f[i] = Integer.MAX_VALUE;
        }
        
        for (int i = 1; i <= n; i++) {
            int l = 0, r = len, mid;
            if (map[a2[i]] > f[len]) {
                f[++len] = map[a2[i]];
            } else {
                while (l < r) {
                    mid = (l + r) / 2;
                    if (f[mid] > map[a2[i]]) {
                        r = mid;
                    } else {
                        l = mid + 1;
                    }
                }
                f[l] = Math.min(f[l], map[a2[i]]);
            }
        }
        System.out.print(len);
    }
}

未通过的代码(传统思路):

分数:50

原因:MLE (超出空间限制)

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] a1 = new int[n];
        int[] a2 = new int[n];
        
        //序列1
        for (int i = 0; i < n; i++) {
            a1[i] = in.nextInt();
        }
        //序列2
        for (int i = 0; i < n; i++) {
            a2[i] = in.nextInt();
        }
        
        System.out.print(f(a1, a2));
    }
    
    public static int f(int[] a1, int[] a2) {
        //题目给的两个序列的长度实现共同的
        //所以定义一个长度变量
        int n = a1.length + 1;
        int[][] dp = new int[n][n];
        int maxl = 0; //最大公共子序列的长度
        
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                if (a1[i-1] == a2[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]);
                }
                maxl = Math.max(maxl, dp[i][j]);
            }
        }
        return maxl;
    }
}

 

力扣 1143. 最长公共子序列

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

  • 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

 

代码:

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        char[] s1 = text1.toCharArray();
        char[] s2 = text2.toCharArray();
        int m = s1.length;
        int n = s2.length;
        int[][] dp = new int[m+1][n+1];  //数组元素默认为 0
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (s1[i-1] == s2[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]);
                }
            }
        }
        return dp[m][n];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dnasZJ2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值