欢迎来到王正伟的博客

返回顶部

面试题42: 连续子数组的最大和(C++)

题目地址:https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/

题目描述

输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)

题目示例

示例1:

输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

解题思路

动态规划:我们假设动态规划列表为f,f(i)代表以元素nums[i]为结尾的连续子数组最大和。根据题目可得转移方程,当f(i-1)<=0时,则产生负贡献,也就是f(i)=f(i-1)+nums[i]的值没有nums[i]的值大,此时f(i)=nums[i],否则f(i)=f(i-1)+nums[i]

贪心思想: 我们利用贪心思想解决这个问题,最容易想到的就是不断累加的过程。当累加的和小于0时,说明对最终结果是负贡献,就从下一个数重新开始,同时更新最大和的值,当累加和大于0时,说明是正贡献,将下一个数值加入和中,同时更新最大和的值。

解题源码

动态规划

class Solution {
public:int maxSubArray(vector<int>& nums) {
        if(nums.size() < 1) return 0;
        int sum = nums[0];
        for(int i = 1; i < nums.size(); i++)
        {
            if(nums[i-1] > 0)
            {
                nums[i] += nums[i-1];
            }
            sum = max(nums[i], sum);
        }
        return sum;
    }
};

贪心法

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size() < 1) return 0;
        int resSum = INT_MIN;
        int curSum = 0;
        for(int i = 0; i < nums.size(); i++)
        {
            if(curSum > 0)
            {
                curSum += nums[i];
            }
            else
            {
                curSum = nums[i];
            }
            resSum = max(curSum, resSum);
        }
        return resSum;
    }
};
posted @ 2020-03-26 01:24  Mr.King~  阅读(988)  评论(0编辑  收藏  举报