1. 程式人生 > >連續子數組的最大和(基於動態規劃)

連續子數組的最大和(基於動態規劃)

動態 pty ostream style http 還要 clu ons 連續子數組

題目

  輸入一個整型數組,數組裏有正數也有負數。數組中一個或連續的多個整數組成一個子數組。求所有子數組的和的最大值。要求時間復雜度為O(n)。例如輸入的數組為{1,-2,3,10,-4,7,2,-5},和最大的子數組為{3,10,-4,7,2},因此輸出為該子數組的和18。

思路

一般解法

  1. 從頭到尾累加數字,保存到一個臨時變量curr_sum中
  2. 如果前幾項的和為負,則加上此和之後比本身的值還要小,拋棄原來所計算得到的和,curr_sum從本元素開始計數 ;否則,把當前元素累加到curr_sum
  3. 把curr_sum與最大值max_sum比較(max_sum保存每個連續數組的最大和)

技術分享圖片

#include <iostream>
#include 
<vector> using namespace std; class Solution { public: int get_max_sum(const vector<int> &v); bool is_invalid{true}; }; int Solution::get_max_sum(const vector<int> &v) { if(v.empty()||v.size()<0) { is_invalid=false; return -1; } is_invalid
=true; int curr_sum=0;//當前和 int max_sum=0;//保存最大和 for(int i=0;i<v.size();++i) { if(curr_sum<=0)//如果前幾項的和為負,則加上此和之後比本身的值還要小,數組從本元素開始計數 curr_sum=v[i]; else curr_sum+=v[i]; if(curr_sum>max_sum) max_sum=curr_sum; }
return max_sum; } int main() { vector<int> v{1,-2,3,10,-4,7,2,-5}; Solution s; cout<<s.get_max_sum(v)<<endl; return 0; }

動態規劃

  f(i)表示以第i個數字結尾的子數組的最大和,那麽只需求出max[f(i)],狀態轉移方程如下

      v[i],i==0||f(i-1)<0
f(i)=
      v[i]+f(i-1),i>0&&f(i-1)>0

code:

#include <iostream>
#include <vector>
using namespace std;

class Solution
{
    public:
        int get_max_sum(const vector<int> &v);
        bool is_invalid{true}; 
};
int Solution::get_max_sum(const vector<int> &v)
{
    if(v.empty()||v.size()<0)
    {
        is_invalid=false;
        return -1;
    }
    
    is_invalid=true;
    int curr_sum=0;//當前和 
    int max_sum=0;//保存最大和 
    
    for(int i=0;i<v.size();++i)
    {
        curr_sum=(curr_sum<0)?v[i]:(v[i]+curr_sum);
        max_sum=max(curr_sum,max_sum);
    }
    return max_sum;
}
int main()
{
    vector<int> v{1,-2,3,10,-4,7,2,-5};
    Solution s;
    if(s.is_invalid) 
        cout<<s.get_max_sum(v)<<endl;
    return 0;
}

連續子數組的最大和(基於動態規劃)