連續子陣列的最大和(基於動態規劃)
阿新 • • 發佈:2019-01-08
題目
輸入一個整型陣列,數組裡有正數也有負數。陣列中一個或連續的多個整陣列成一個子陣列。求所有子陣列的和的最大值。要求時間複雜度為O(n)。例如輸入的陣列為{1,-2,3,10,-4,7,2,-5},和最大的子陣列為{3,10,-4,7,2},因此輸出為該子陣列的和18。
思路
一般解法
- 從頭到尾累加數字,儲存到一個臨時變數curr_sum中
- 如果前幾項的和為負,則加上此和之後比本身的值還要小,拋棄原來所計算得到的和,curr_sum從本元素開始計數 ;否則,把當前元素累加到curr_sum
- 把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; }