题目链接
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; } };