大o
記號:如果存在正常數c和
c0 使得當
n>=n0
時t(n)<=cf(n),
則記為t(n) = o(f(n))在大o
記號中比較的其實是
「相對增長率
」,其實也就是求導後的比較。對於具體的數值是沒有意義。比如:某個
n0使得
f(n0)0)
是沒有意義的。
當t(n) = o(f(n))
時,f(n)
是t(n)
的乙個「上界」
。幾個結論:
結論一:如果
t1(n) = o(f(n))
且t2(n) = o(g(n)),
那麼a) t1(n) + t2(n) = o(f(n) + g(n));
或者寫成
max( o(f(n)) , o(g(n)) ).
b) t1(n) * t2(n) = o(f(n) * g(n));
結論二:對於任意常數k,
logkn = o(n),
說明對數增長的很慢。
問題描述:給定(包括負數)整數
a1,a2,a3 ... an,
求∑jk=iak
的最大值。
例子:對於
-2 11 -4 13 -5 -2
答案為20 解法
1)直接列舉所有子串行:
public static int maxsubsum(int a)}}
return maxsum;
}時間複雜度
o(n2)
解法二)
分治法:
像一般的分治法一樣,分為
divide-conquer-combine
幾個階段。
具體為a)
以中點將序列分為兩段
(divide)b)
遞迴求兩段的最大子串行
c)求以中點為軸向兩邊蔓延的最大子串行,並和
b)求的兩個值比較,
return
其中的最大值。
public static int maxsumrec(int a, int left, int rigth)
int center = (left + right) / 2;//divide
int maxleftsum = maxsumrec(a, left, center);//sub problem
int maxrightsum = maxsumrec(a, center + 1, right);//sub problem
int maxleftbordersum = 0;
int leftbordersum = 0;
for(int i = center; j >= left; i--)
}int maxrightbordersum = 0;
int rightbordersum = 0;
for(int i = center + 1; i <= right; i++)
}if(maxleftsum < maxrightsum)
if(maxleftsum < maxleftbordersum + maxrightbordersum)
return maxleftsum;
}public static int maxsubsum(int a)
時間複雜度為o(
nlogn
)解法三)
此題有一種線性時間的解法,而且只需要一次掃瞄即可得到答案,即所謂「聯機演算法」(
on-line algorithm
)public static int maxsubsum(int a)
return maxsum;
}
資料結構 最大子串行和
最近我打算重溫一遍資料結構,於是又遇到了求最大子串行和這一基本問題。記得之前我就沒有明白透徹,這次便記錄下來。求最大子串行和,即求乙個序列中,和值最大的連續子串行。首先採用暴力解法,即求出所有的子串行和,得到最大和,這個演算法的時間複雜度是o n 2 int maxsubsum int k,int ...
資料結構 最大子串行號
01 複雜度1 最大子列和問題 20分 給定k 個整數組成的序列,連續子列 被定義為,其中 1 i j k。最大子列和 則被定義為所有連續子列元素的和中最大者。例如給定序列,其連續子列有最大的和20。現要求你編寫程式,計算給定整數序列的最大子列和。輸入第1行給出正整數k 100 000 第2行給出 ...
資料結構與演算法分析 最大子串行和問題
最大連續子數列和一道很經典的演算法問題,給定乙個數列,其中可能有正數也可能有負數,我們的任務是找出其中連續的乙個子數列 不允許空序列 使它們的和盡可能大。我們一起用多種方式,逐步優化解決這個問題。例 輸入時,答案為 20 從a2到 a4 演算法1 include n是陣列長度,a是待計算的陣列,放在...