Leetcode算法初学——动态规划算法“最大子序和”

题目:

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

 

示例:

 

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

题解:

  拿到题的第一想法是暴力搜索,两个嵌套循环遍历搜索循环比较最大值,最后返回最大值

 

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) {
 4         int max=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=sum+nums[j];
11                if(sum>max)
12                {
13                    max=sum;
14                }
15            }
16        }
17        return max;
18     }
19 };

 

成功通过检测:

 

可以看到,虽然成功通过了检测,但是显示执行用时过长,时间复杂度为O(n2),于是转换思路用动态规划,先确定动态规划转移方程,可以想到,当n=1时,最大值为n1,当n=2时,最大值要么为n1,要么为n2要么就为n1+n2,与爬楼梯很相似,尽管爬楼梯的边界是固定的,而最大子序和要比爬楼梯略微复杂一些,它可以从中间任何地方取值,但是原理相似,最小子序和就是取前n个数的最大值与后一个数以及与后一个数的和作比较取最大值,所以只要用一个if循环,里面加两个判断就可以做出来,并且因为只用取一个值而不用列出情况,可以只设常数空间而不用设立数组,空间复杂度为O(1),时间复杂度为O(n):

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int> &nums)
 4     {
 5          int Max = INT_MIN;
 6          int db;
 7          db = nums[0];
 8            Max = db;
 9          for (int i = 1; i < nums.size(); i++)
10         {
11                 if (db + nums[i] > nums[i])
12         {
13             db = db + nums[i];
14         }
15         else { db = nums[i]; }
16         if (db > Max)
17         {
18             Max = db;
19         }
20     }
21     return Max;
22     }
23 
24 };

成功通过检测:

 

 可以看出,相比较嵌套循环暴力搜索,时间节省了很多,这就是动态规划算法的好处。

 

posted @ 2020-06-14 16:16  菲特涅米  阅读(104)  评论(0编辑  收藏  举报