時間複雜度從O n 3 到O n 2 的優化

2021-08-08 17:51:14 字數 1918 閱讀 5980

給定由n個整數a[0],a[1],a[2],a[3],….a[n-1]組成的陣列a。你想輸出乙個二維的n*n的陣列b,

其中陣列b[i,j] (i

for i =0,1,2,...n-2

for j = i+1,i+2,....n-1

將a[i]->a[j]的累加和賦值給b[i,j]

由於要滿足j>i,這樣來說二維矩陣的對角線是不需要進行計算的,而且最後一行一直是j>=i也不用計算,所以第一層for迴圈是[0~n-2]

外層迴圈運算次數n級別,內層用高斯求和n^2級別,所以時間複雜度是o(n^3)

for

i = 0,1,2...n-2

b[i]

[i+1] = a[i] + a[i+1]

fori = 0,1,2,3...n-2

forj = i+2,i+3,....n-1

b[i]

[j] = b[i]

[j] + a[j]

思路:

b[0][1] = a[0] + a[1]

b[0][2] = a[0] + a[1] + a[2] = b[0][1] + a[2]

b[0][3] = a[0] + a[1] + a[2] + a[3] = b[0][2] + a[3]

。。。

b矩陣的b[i][j] = b[i][j-1] + a[j],這樣中間的計算結果能夠被利用,而且減少了重複的計算。

分析演算法,第一次for迴圈o(n),第二次兩個for迴圈o(n^2),所以整個演算法的時間複雜度是o(n^2)

"""

給定由n個整數a[1],a[2],a[3],....a[n]組成的陣列a。你想輸出乙個二維的n*n的陣列b,

其中陣列b[i,j](i=j,

陣列的項b[i,j]的值不用指定,因此不管這些值的輸出.)

"""def

fun(a):

n = len(a)

b = [[0

for i in range(0,n)] for j in range(0,n)]

for i in range(0,n-1):

for j in range(i+1,n):

sum = (a[i]+a[j])*(j-i+1)//2

b[i][j] = sum

return b

deffun2

(a):

n = len(a)

b = [[0

for i in range(0,n)] for j in range(0,n)]

for i in range(0,n-1):

b[i][i+1] = a[i] + a[i+1]

for i in range(0,n-1):

for j in range(i+2,n):

b[i][j] = b[i][j-1] + a[j]

return b

deftest

(): a = [1,2,3,4,5]

result = fun(a)

for i in range(len(a)):

print(result[i])

deftest2

(): a = [1,2,3,4,5]

result = fun2(a)

for i in range(len(a)):

print(result[i])

if __name__ == '__main__':

test()

print("*****")

test2()

程式有待驗證,如有錯誤謝謝指出

最大子串行和整理,複雜度從O n 3 到O n

求乙個序列的子串行的最大值,這是乙個經典演算法,這裡稍作整理。問題 任給乙個整數序列,如,求出這個序列中連續子串行的和的最大值,這個例子中最大值為32,子串行為。方法一 最簡單的暴力法。確立乙個起點,乙個終點,計算起點到終點的和。下面 中int brute force int a,int n 實現了...

基於比較氣泡排序 時間複雜度O n 2

只操作相鄰的兩個資料,每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關係要求,如果不滿足讓它兩互換。一次冒泡會讓至少乙個元素移動到它應該在的位置,重複 n 次,就完成了 n 個資料的排序工作。eg 對於一組資料 4 5 6 3 2 1第一次冒泡的過程 經過了 5 次比較,此時 3 已經在正...

排序演算法之時間複雜度為O N 2 的演算法

背景知識 排序演算法算是比較基礎的演算法了,但是在面試過程中偶爾也會被問到,雖然很多語言都內建了排序函式,例如php的sort函式等等,但是還是有必要聊聊排序演算法,這篇文章中將介紹時間複雜度為o n 2 的幾個排序演算法。本文基於從小到大排序講解。1.氣泡排序 前乙個和後乙個比較,如果前乙個比後乙...