当前位置:首页 > 力扣 > 力扣2771题解析:双数组动态规划求解最长非递减子数组问题

力扣2771题解析:双数组动态规划求解最长非递减子数组问题

5个月前 (06-27)

力扣2771题解析:双数组动态规划求解最长非递减子数组问题  动态规划 最长递增子序列 双数组DP 算法优化 第1张

一、题目解读

力扣2771题要求从两个整数数组nums1和nums2中合并元素,寻找最长非递减子数组的长度。非递减子数组指元素单调递增或相等的连续序列。题目难点在于需同时考虑两个数组的交互关系,找到全局最优解。

二、解题思路

动态规划(DP)策略。定义两个DP数组dp1[i]和dp2[i],分别表示以nums1[i]和nums2[i]结尾的最长非递减子数组长度。核心在于利用双数组处理两数组的交叉选择:每个位置可视为选择当前数组元素或延续另一数组的前缀结果。通过状态转移方程更新最大值,最终取dp1和dp2中的全局最大值。

三、解题步骤

1. 初始化:dp1和dp2初始值均为1(单个元素即合法子数组)。

2. 迭代处理:

    若nums1[i]≥nums1[i-1],则dp1[i]可延续dp1[i-1];

    若nums1[i]≥nums2[i-1],则dp1[i]可承接dp2[i-1](跨数组合并);

    同理处理dp2[i]的两种情况。

3. 全局更新:每次迭代后比较dp1[i]和dp2[i],取最大值存入max_len。

4. 返回结果:max_len即为最终答案。

四、代码与注释

class Solution {
public:
    int maxNonDecreasingLength(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        if (n == 0) return 0;
        
        // dp1[i]表示选择nums1[i]时的最长非递减子数组长度
        // dp2[i]表示选择nums2[i]时的最长非递减子数组长度
        vector<int> dp1(n, 1), dp2(n, 1);
        int max_len = 1;
        
        for (int i = 1; i < n; ++i) {
            // 当前选择nums1[i]的情况
            if (nums1[i] >= nums1[i-1]) {
                dp1[i] = max(dp1[i], dp1[i-1] + 1); // 延续nums1前缀
            }
            if (nums1[i] >= nums2[i-1]) {
                dp1[i] = max(dp1[i], dp2[i-1] + 1); // 跨数组合并
            }
            
            // 当前选择nums2[i]的情况
            if (nums2[i] >= nums1[i-1]) {
                dp2[i] = max(dp2[i], dp1[i-1] + 1);
            }
            if (nums2[i] >= nums2[i-1]) {
                dp2[i] = max(dp2[i], dp2[i-1] + 1); // 延续nums2前缀
            }
            
            // 更新全局最大值
            max_len = max(max_len, max(dp1[i], dp2[i]));
        }
        
        return max_len;
    }
};

五、总结

本解法通过双DP数组巧妙处理双数组交叉选择问题,时间复杂度O(n),空间复杂度O(n)。动态规划的关键在于明确状态定义和转移逻辑,适用于需要全局最优解且存在重叠子问题的场景。理解两数组元素的“可衔接性”是解题核心。

原创内容 转载请注明出处

分享给朋友:

相关文章

力扣5:中心扩散法 轻松破解最长回文子串

力扣5:中心扩散法 轻松破解最长回文子串

题目解读:在一个给定的字符串中,我们需要找到最长的回文子串。回文是指正读反读都相同的字符串,如"aba"、"abba"都是回文。这个问题看似简单,但要在字符串中...

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

题目重解:数字三角形是一个经典的动态规划问题,给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们需要找到一条路径,使得路径上经过的数字总和最大。这个问题可以很...

NOIP 2008火柴棒等式题解(C++代码实现)  动态规划与枚举算法详解

NOIP 2008火柴棒等式题解(C++代码实现) 动态规划与枚举算法详解

一、题目解读火柴棒等式问题(NOIP 2008,洛谷P1149)要求使用给定数量的火柴棒,构造形如 A + B = C 的等式,其中A、B、C均为整数,且火柴棒总数恰好等于输入值。需统计符合条件的等式...

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

一、题目解读洛谷P4551题要求在一个无向图中,寻找任意两点路径权值异或后的最大值。题目输入为图的边信息(点数n和n-1条边),每条边包含起点、终点及权值。需输出所有路径中权值异或的最大值。问题核心在...

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

一、题目解读CSP-J 2019年的“公交换乘”题目(洛谷P5661)要求模拟地铁与公交交替出行的费用计算。题目核心在于地铁消费会产生优惠券,而公交可在45分钟内使用优惠券抵扣车费。需要处理n条出行记...

1999年NOIP提高组导弹拦截(洛谷P1020)解题思路与动态规划代码解析

1999年NOIP提高组导弹拦截(洛谷P1020)解题思路与动态规划代码解析

一、题目解读    1999年NOIP提高组“导弹拦截”问题(对应洛谷P1020)要求设计导弹拦截系统:给定一组导弹高度数据,需计算最少拦截系统数量,并求最多能...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。