leetcode 53.最大子序和

常规的暴力解法,所有排列组合情况试一遍,时间复杂度为O(n^2)

 

以leetcode的测试集来看,效率最高的是贪心法。从开头到结尾依次加,如果sum<0了,那么求和器sum归零。时间复杂度为O(n)。

代码如下

 1 //贪心法
 2 class Solution {
 3 public:
 4     int maxSubArray(vector<int>& nums) {
 5         int Ret=nums[0],sum=0;
 6         for(int i=0;i<nums.size();++i){
 7             sum+=nums[i];
 8             Ret=Ret>sum?Ret:sum;
 9             if(sum<0)sum=0;
10         }
11         return Ret;
12     }
13 };

 

比较经典的解法有动态规划和分治法。时间复杂度都为O(n)。其中DP效率还不错且实现简单。但分治法实现比较复杂,效率也略微不如DP。

DP的思路为从局部最优解逐步向全局最优解靠近。

以下为DP法代码

 1 //DP法
 2 class Solution {
 3 public:
 4     int maxSubArray(vector<int>& nums) {
 5         if(nums.size()==0)return 0;
 6         if(nums.size()==1)return nums[0];
 7         int pre=nums[0],res=nums[0];
 8         for(int i=1;i<nums.size();++i){
 9             pre=max(nums[i],pre+nums[i]);
10             res=max(res,pre);
11         }
12         return res;
13     }
14 };

分治法思路是,取中间节点,最大子序列要么都在左边,要么都在右边,要么是跨中点的。对于跨中点的情况,用暴力法从中点向两边求和,分别求出左段以中点为结尾的最大子序列和以及右段以中点为起点的最大子序列和,两者相加。

递归回来后,从三种情况中选最大值。实现方法略。

虽然分治法在效率和实现上不如DP。但分治法的优点是,可以查询任意区间[l,r]的最大子序列和,在构造整个递归树结构之后,后续的查询代价仅为O(logn),这在实际应用中更有意义。

posted @ 2020-08-19 17:12  布羽  阅读(83)  评论(0)    收藏  举报