LeetCodeb动态规划子序列问题——1035.不相交的线

1035. 不相交的线icon-default.png?t=M4ADhttps://leetcode.cn/problems/uncrossed-lines/

在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。

现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足:

  •  nums1[i] == nums2[j]
  • 且绘制的直线不与任何其他连线(非水平线)相交。

请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。

以这种方法绘制线条,并返回可以绘制的最大连线数。

LeetCodeb动态规划子序列问题——1035.不相交的线_第1张图片

 

分析:

牢记动态规划五步:

1.确定dp数组含义

2.确定递推公式

3.dp数组初始化

4.确定遍历顺序

01背包问题:一维dp的遍历,商品放在外循环,背包在内循环,且内循环倒序。

求组合:先遍历商品,再遍历背包

求排列:先便利背包,再遍历商品

求最大最小:对遍历顺序没有要求

5.举列推导

代码:

class Solution {
    /*思路:
    直线不能相交,这就是说明nums1中找到一个与字nums相同的子序列
    只要相对顺序不改变,链接相同数字的直线就不会相交。
    求绘制的最大连线数,其实就是求两个数组的最长公共子序列的长度!
    */
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        int len1=nums1.length;
        int len2=nums2.length;
        int[][] dp=new int[len1+1][len2+1];
        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]);
                }
            }
        }
        return dp[len1][len2];
    }
}

动态规划做题方法:

做动规题目的时候,很多同学会陷入一个误区,就是以为把状态转移公式背下来,照葫芦画瓢改改,就开始写代码,甚至把题目AC之后,都不太清楚dp[i]表示的是什么。这就是一种朦胧的状态,然后就把题给过了,遇到稍稍难一点的,可能直接就不会了,然后看题解,然后继续照葫芦画瓢陷入这种恶性循环中。 确定递推公式仅仅是动态规划解题的一步!知道递推公式,但不知道dp数组要怎么初始化,数组要怎么正确的遍历

所以,我们始终牢记动态规划五步:

1.确定dp数组含义

2.确定递推公式

3.dp数组初始化

4.确定遍历顺序

5.举例推导

做题之前,可以自己先思考这三个问题:

  • 这道题目我举例推导状态转移公式了么?
  • 我举例推导dp数组了嘛?
  • 打印出来的dp数组和我想的一样么?

后序的跟着博主解题,大家就会慢慢感受到这五步的重要性了。

博主会持续更新LeetCode的题解和Java学习过程的问题噢(都按照题型进行分类啦~),如果对你有帮助的话,请帮博主点个赞,关注博主一起成长吧!

你可能感兴趣的:(LeetCode__动态规划,动态规划,算法)