【LeetCode】23.最大子序和

题目链接

https://leetcode-cn.com/problems/maximum-subarray/

题目描述

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

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

解题思路

对于任何的题目,首先都要思考一下能不能利用暴力的求解方法。

解法一:暴力

暴力还是典型的双重for循环,时间复杂度O(n2)。

因为具有最大子序和的连续数组一定是以数组中某个元素开始的,所以我们只要枚举出数组中每个元素开始的最大的连续子数组和,在进行比较即可。

解法二:动态规划

求解动态规划问题的核心在于dp数组表示的含义以及状态转移方程的求解。

该题中dp数组中存储的元素dp[i]表达的含义是以nums[i]元素结尾的最大子序和。

 

AC代码

解法一:暴力搜索(超时版本)

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) {
 4         int ans = INT_MIN;//类似寻找最大最小值,初始化都要设置为理论上的最大最小值,INT_MIN与INT_MAX
 5         for(int i = 0; i < nums.size(); i++)
 6         {
 7             int sum = 0;
 8             int temp = INT_MIN;
 9             for(int j = i; j < nums.size(); j++)
10             {
11                 sum += nums[j];
12                 temp = max(temp,sum);//该版本的暴力方法超时的原因在12,14行是可以合并在一起,可以减少O(n)次max运算。
13             }
14             ans = max(ans,temp);
15         }
16         return ans;
17     }
18 };

暴力搜索(刚好AC)

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) {
 4         int ans = INT_MIN;
 5         for(int i = 0; i < nums.size(); i++)
 6         {
 7             int sum = 0;
 8             for(int j = i; j < nums.size(); j++)
 9             {
10                 sum += nums[j];
11                 ans = max(ans,sum);
12             }
13         }
14         return ans;
15     }
16 };

解法2:DP

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        vector<int> dp;
        dp.resize(nums.size());
        int num = nums[0];
        dp[0] = num;
        int ans = max(INT_MIN,dp[0]);
        for(int i = 1; i < nums.size(); i++)
        {
            dp[i] = max(dp[i-1]+nums[i],nums[i]); //状态转移方程
            ans = max(ans,dp[i]);
        }
        return ans;
    }
};

猜你喜欢

转载自www.cnblogs.com/XDU-Lakers/p/12821367.html
今日推荐