0
点赞
收藏
分享

微信扫一扫

[C语言][剑指offer篇]--连续子数组的最大和(动态规划)

南陵王梁枫 2022-03-30 阅读 80

1.题目描述

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
在这里插入图片描述
提示:
1 <= arr.length <= 10^5
-100 <= arr[i] <= 100



2.理清思路

2.1 动态规划

 将一个问题拆解成几个小问题,分别求出小问题的解,即可推出大问题的解,那么如何判定能否用动态规划解问题?答案是满足以下两个条件:

  • 具有最优解(题目中出现最多,最少,最大,最…)。
  • 可以将大问题拆解成几个小问题来求解。

2.2 如何设计动态规划

  • 根据题意,假设大问题的最优解。
  • 根据大问题的最优解,能够推测出小问题的最优解,从而找到通用表达式,即状态转移方程。
  • 根据状态转移方程设计代码逻辑。

2.3 题解

  • 题目中出现 “最大” ,因此具有最优解,假设f(i)为以第i个元素结尾的子数组的最大和。
  • 那么f(i)应该如何计算?根据题意 “连续子数组” ,说明f(i) = f(i-1)+nums[i],依次类推,f(i-1) = f(i-1-1)+nums[i-1],f(i-1-1) = f(i-1-1-1)+nums[i-1-1]… , 大问题拆解成了若干小问题,最终大问题的解,即为f(i)中的最大值。
  • 考虑 f(i) 与 f(i-1)的关系。如果f(i-1)+nums[i] <= nums[i],则f(i)取nums[i],表示以i结尾的连续子数组的最大值为nums[i],因为单独一个nums[i]也是子数组。如果f(i-1)+nums[i] > nums[i],则f(i)取f(i-1)+nums[i]。即:f(i) = MAX{f(i-1)+nums[i],nums[i]},{ i >= 0 && i < n} 。
  • 经过前面的分析,最终大问题的解,即为f(i)中的最大值,因此需要用一个max标记出所有f(i)中的最大值,方便计算完所有f(i)后直接返回f(max)。

3. 代码实现

int maxSubArray(int* nums, int numsSize){

    int f[numsSize+1];
    int i = 0;
    int max = 0;
    
    if(nums == NULL)
    {
        return -101;
    }

    f[0] = nums[0];

    for(i = 1; i < numsSize; i++)
    {
        if((f[i-1] + nums[i]) <= nums[i])
        {
            f[i] = nums[i];
        }
        else
        {
            f[i] = f[i-1] + nums[i];
        }

        if(f[max] < f[i])
        {
            max = i;
        }
    }

    return f[max];

}
举报

相关推荐

0 条评论