动态规划:面试题42. 连续子数组的最大和

面试题42. 连续子数组的最大和

题目要求:

 

 解题思路:

 1. 定义子问题:

  dp[i] 为下标以 num[i] 结尾的数组字段 元素最大最短和,i表示子段到当前i位置 i;

2. 寻找关系式:

  只有一个元素:dp[0] = num[0];

  两个元素:dp[i] 为num[0], num[1], num[0]+num[1]; 

  三个元素时:考虑前三个元素,如何求其最⼤大⼦子段和?还是分为两种情况讨论,第三个元素在最后的字串串内吗?
    若第三个元素也包含在最后的字串串内,则dp[2] = max(dp[1]+num[2] , num[2]) ;

  所以转移方程为:dp[i] = max(dp[i-1] + num[i],  num[i] ) ;

3. 初始值:

  dp[0] = nums[0];
  dp[1] = max(dp[0]+num[1] , num[1]) ;

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) 
 4     {
 5         int len = nums.size();
 6         if (len < 1)
 7         {
 8             return 0;
 9         }
10         int* dp = new int[len]; 
11         //int[] dp = new int[len]  //不支持
12         dp[0] = nums[0];
13         int max = dp[0];
14         for (int i=1; i<len; i++)
15         {
16             dp[i] = std::max(dp[i-1] + nums[i],  nums[i]);
17             if (dp[i] > max)
18             {
19                 max = dp[i];
20             }
21         }
22         return max;
23     }
24 };

 

 

优化:在原数组的基础上进行更改。

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) 
 4     {
 5         int len = nums.size();
 6         if (len < 1)
 7         {
 8             return 0;
 9         }
10         //int* dp = new int[len]; 
11         //int[] dp = new int[len]  //不支持
12         //dp[0] = nums[0];
13         int max = nums[0];
14         for (int i=1; i<len; i++)
15         {
16             //dp[i] = std::max(dp[i-1] + nums[i],  nums[i]);
17             if (nums[i-1] > 0)
18             {
19                 nums[i] += nums[i-1];
20             }
21             if (nums[i] > max)
22             {
23                 max = nums[i];
24             }
25         }
26 
27         return max;
28     }
29 };

 

posted @ 2020-04-06 10:30  Ternence_zq  阅读(232)  评论(0编辑  收藏  举报