關於求最大連續子串行和O(n)的一些思考

2021-09-13 01:38:09 字數 1874 閱讀 9640

首先,這個問題並不複雜,有o(n^2)的字首和做法,還有分治o(nlgn)的做法。

還有o(n)的做法。

o(n)的做法,目前我知道了兩種。

一種就是

sum[i,j] = sj - s(i-1),先計算字首和,然後從左往右記錄當前碰到的最小字首和的下標,因為固定sj,就要使s(i-1)最小。然後在從左往右跑一遍,即可。

這種做法需要計算字首和,和預處理相應的下標。總共多需要兩個陣列。

接下來的一種做法,節約了空間。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

typedef

long

long ll;

#define inf 0x3f3f3f3f

#define pi acos(-1.0)

#define pii pair

#define all(x) x.begin(),x.end()

#define mem(a,b) memset(a,b,sizeof(a))

#define per(i,a,b) for(int i = a;i <= b;++i)

#define rep(i,a,b) for(int i = a;i >= b;--i)

const

int maxn =

3e5;

int n =

0,m =0;

int a[maxn+10]

;int s[maxn+10]

;int sm[maxn+10]

;//記錄從1-j中最小的s的下標i,s[j] - s[i-1]最大,固定 s[j],相當於使s[i-1]最小

//然後掃瞄一次陣列,維護目前遇到過的最小s

//複雜度o(n)

intmain()

int mins =

0,min_id =0;

sm[1]

=0;per

(i,2

,n)else

}int maxv =

-inf;

per(i,

1,n)

}printf

("%d %d : %d\n"

,l,r,maxv);}

return0;

}

2,設s[i]表示以a[i]結尾的連續子串行的最大和。由於遞推s[i]陣列可以節約為乙個變數即可。

#include

#define per(i,a,b) for(int i = (a);i <= (b);++i)

#define inf 0x3f3f3f3f

using namespace std;

const

int maxn =

3e5;

int a[maxn+10]

;int n =0;

void

solve()

}else}}

printf

("the maximum is %d\nthe internal is %d to %d\n"

,maxv,l,r);}

intmain()

solve()

;}return0;

}

第二種為什麼比第一種方法節約空間。

前者不是增量演算法,後面的演算法通過增量遞推,充分利用了每一步的計算結果。增量,這種xx,在很多方面都有很好的應用,可以是演算法變得高效。

關於求最大連續子串行 和 問題

昨天看到乙個演算法題目,題目是這樣子的 輸入一組整數,求出這組數字子串行和中最大值。也就是只要求出最大子串行的和,不必求出最大的那個序列。例如 序列 2 11 4 13 5 2,則最大子串行和為20。序列 6 2 4 7 5 3 2 1 6 9 10 2,則最大子串行和為16。這個題目也是在csdn...

求最大連續子串行的和

小王的賬本 小王出門打零工,工作很不穩定,收入也很不穩定,他找了乙個賬本記錄他每天的支出,例如 1月1日 收入320 1月2日 沒找到工作,吃飯花了30 1月3日 掙50 1月4日 無工作,吃飯花了17 1月5日 無工作,租房 吃飯花了2600 年底了,小王想知道自己賬本上哪一段時間掙錢掙的最多。剛...

最大連續子串行和

最大連續子串行和問題是個很老的面試題了,最佳的解法是o n 複雜度,當然其中的一些小的地方還是有些值得注意的地方的。這裡還是總結三種常見的解法,重點關注最後一種o n 的解法即可。需要注意的是有些題目中的最大連續子串行和如果為負,則返回0 而本題目中的最大連續子串行和並不返回0,如果是全為負數,則返...