※ Leetcode - Dynamic Programming - 53.Maximum Subarray(最大连续和)+152.Maximum Product Subarray(最大连续积)

本文探讨了两个经典算法问题:最大连续子数组之和与最大连续子数组之积。通过对状态转移方程的深入分析,提出了高效求解方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Problem Description of 53.Maximum Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

 

For example, given the array [2,1,3,4,1,2,1,5,4],

the contiguous subarray [4,1,2,1] has the largest sum = 6.

求一个数组的最大连续和

 

2. My solution

这类问题需要关注的核心问题是:

 

局部最优解如何求得,和全局最优解的关系(状态转移方程的确定)

 

该题的状态转移方程,仅考虑两个值得大小:Local[i-1]+nums[i]nums[i]

因此:Local[i]=max([i-1]+nums[i],nums[i])

  int maxSubArray(vector<int>& nums)
    {
        vector<int>local;
        int len=nums.size();
        //range of int:-(1<<31)~(1<<31)-1
        
        if(len==1)
            return nums[0];
        local.push_back(nums[0]);
        int global=local[0];
        for(int i=1; i<len; i++)
        {
           local.push_back(max(local[i-1]+nums[i],nums[i]));
           global=max(global,local[i]);
        }
        return global;
    }

3. Problem Description of 152. Maximum Product Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest product.

 

For example, given the array [2,3,-2,4],

the contiguous subarray [2,3] has the largest product = 6.

求数组中元素的最大连续积。

4. My solution

题目与最大连续和的区别关键在于我们不能只考虑前一个最大数与当前数的和。

因为负数的存在,很可能一个绝对值较大的负数,和一个负数相乘得到一个很大的证书。

所以除了记录局部最大值,我们还应该记录局部最小值。

因为nums[i]的正负未知,我们直接把前一个局部最大值和局部最小值分别与nums[i]相乘。

得到:

 int tmin=minlocal[i-1]*nums[i];

 int tmax=maxlocal[i-1]*nums[i];

最后当前的局部最大值和局部最小值,通过比较三个数得到:

Tmin,tmax,nums[i]

然后更新global值就可以啦~


  int maxProduct(vector<int>& nums)
    {
        int len=nums.size();
        if(len==1)
            return nums[0];
        vector<int>minlocal;
        vector<int>maxlocal;
 
        minlocal.push_back(nums[0]);
        maxlocal.push_back(nums[0]);
        int global=nums[0];
 
        for(int i=1; i<len; i++)
        {
            int tmin=minlocal[i-1]*nums[i];
            int tmax=maxlocal[i-1]*nums[i];
            minlocal.push_back(min(min(tmin,tmax),nums[i]));
            maxlocal.push_back(max(max(tmin,tmax),nums[i]));
            global=max(maxlocal[i],global);
        }
        return global;
    }


### LeetCode 298 二叉树最长连续序列 对于LeetCode上的编号为298的题目“二叉树中最长的连续序列”,目标是在给定的二叉树中找到最长的连续递增路径长度。这里的连续意味着节点值依次增加1。 #### 解决方案概述 解决方案涉及深度优先搜索(DFS)遍历整棵树,同时跟踪当前路径是否构成连续递增序列以及该序列的长度。当遇到不满足条件的情况时,则重置计数器并继续探索其他分支[^4]。 #### Python代码实现 下面是一个基于上述思路的具体Python实现: ```python class Solution(object): def longestConsecutive(self, root): """ :type root: TreeNode :rtype: int """ def dfs(node, parent_val, cur_length): if not node: return # 如果当前节点值正好是父节点值加一,则认为找到了一个新的连续部分 if node.val == parent_val + 1: nonlocal max_length max_length = max(max_length, cur_length + 1) # 继续向下层传递更新后的参数 dfs(node.left, node.val, cur_length + 1) dfs(node.right, node.val, cur_length + 1) else: # 否则重新开始计算新的潜在连续序列 dfs(node.left, node.val, 1) dfs(node.right, node.val, 1) max_length = 0 # 初始化调用栈 dfs(root, float('-inf'), 0) return max_length ``` 此方法通过递归方式访问每一个节点,并利用`parent_val``cur_length`两个额外参数来帮助判断是否存在连续关系及其对应的长度变化情况。最终结果保存于全局变量`max_length`之中,在完成整个树形结构扫描之后返回作为答案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值