宣告:本筆記所涉及的資料**於牛客網常數時間的操作:乙個操作如果和資料量沒有關係,每次都是固定時間內完成的操作,叫做常數操作。我的理解是這種操作最終的執行就是執行彙編命令,而彙編命令執行花費的時間都是有限的機器時鐘時間,可以簡單理解為執行乙個相加指令,所以常數操作花費的時間是確定有限的,和數量級沒關係。
時間複雜度為乙個演算法流程中,常數運算元量的指標,常用o(讀作 big o)來表示。具體來說,在常數運算元量的表示式中,只要有高階項,不要低階項,也不要高階項的係數,剩下的部分如果記為f(n),那麼時間複雜度為o(f(n))。
評價乙個演算法流程的好壞,先看時間複雜度的指標,然後再分析不同資料樣本下的實際執行時間,也就是常數項時間。
乙個有序陣列a,另乙個無序陣列b,請列印b中的所有不在a中的數,a陣列長度為n,b陣列長度為m。
這相當於兩個for迴圈,所以常數操作量f(m,n) = m * n ,所以演算法複雜度為o(m * n)
二分查詢常數操作量約為log2n,所以總的演算法複雜度為o(m * logn),log下標可省,一般看做2
排序時間複雜度可為o(m * logm),外排列印時間複雜度為o(m + n),所有總的時間複雜度為o(m * logm) + o(m + n)所以具體演算法的優劣還要看實際的數量級,演算法二肯定比演算法一要優,演算法二和演算法三需要考慮m,n的取值範圍來判斷
第一次冒:0 ............. n-1
第二次冒:0 ....... n-2
第三次冒:0 ... n-3
直到冒完
所有偽**可以這樣:
public static void bubblesort(int arr)
for (int e = arr.length - 1; e > 0; e--) }}
}
可知當數量級為n時,常數操作量就是n*n,時間複雜度就為o(n^2),空間複雜度因為只是操作原陣列,沒有聲請什麼額外的空間,所以為常數,額外空間複雜度為o(1)
第一次從0 .................n-1中選擇出最小(大)值放在0
第二次從 1 .................n-1中選擇出最小(大)值放在1
第三次從 2 .................n-1中選擇出最小(大)值放在2
知道選擇完
偽**:
public static void selectionsort(int arr)
for (int e = 0; e < arr.length-1; e ++)
swap(arr,e,min);
}}
同理:時間複雜度o(n^2),額外空間複雜度o(1)
遞迴的實現實質是方法資料的棧的壓入和彈出,壓入或彈出的資料即為方法的一些屬性資料,如方法指標,引數,結果等
最典型的應用就是歸併排序
套路就是:最外面一層把主問題分為兩個小問題,加乙個merge處理塊
套路公式:
master公式:t(n) = a * t (n / b) + o(n ^ d)
a 為子規模執行次數,b 為主規模分了幾個子規模,d 為merge處理的負責度裡的n的係數
例:歸併排序
public static void mergesort(int arr)
mergesort(arr, 0, arr.length - 1);
}public static void mergesort(int arr, int l, int r)
int mid = l + ((r - l) >> 1);
mergesort(arr, l, mid);
mergesort(arr, mid + 1, r);
merge(arr, l, mid, r);
}public static void merge(int arr, int l, int m, int r)
while (p1 <= m)
while (p2 <= r)
for (i = 0; i < help.length; i++)
}
最外層將主規模分為了2個子規模f(n/2)執行,所以a = 2,b = 2,merge處理複雜度為o(2n) = o(n) ,所以d = 1,所以t(n) = 2(n/2) + o(n)額外空間複雜度為o(n),主要是每次merge都申請了新的陣列空間所以log(b,a) = d = 1 ,時間複雜度為o(n * logn)
小和問題
public static void main(string args)
public static void smallsum(int arr)
system.out.println("原陣列");
util.printarray(arr);
system.out.println("");
int smallsum = deal(arr,0,arr.length-1);
system.out.println("處理後的陣列:");
util.printarray(arr);
system.out.println("小和為:"+smallsum);
}public static int deal(int arr,int left,int right)
int middle = left + ((right-left)>>1);
return deal(arr,left,middle) + deal(arr,middle+1,right)+merge(arr,left,middle,right);
}public static int merge(int arr,int left,int middle,int right)
sum += arr[p1] < arr[p2]? (right-p2+1)*arr[p1]:0;
help[index++] = arr[p1] < arr[p2]? arr[p1++] : arr[p2++];
}while (p1 <= middle)
while (p2 <= right)
for (int i = 0;i < help.length;i++)
return sum;
}
隨機測試結果:
測試結果
在乙個陣列中,左邊的數如果比右邊的數大,則折兩個數構成乙個逆序對,請列印所有逆序對。
public static void main(string args)
public static void nixudui(int arr)
public static void deal(int arr,int left,int right)
int middle = left + ((right-left)>>1);
deal(arr,left,middle);
deal(arr,middle+1,right);
merge(arr,left,middle,right);
}public static void merge(int arr, int left,int middle, int right)
help[i++] = arr[p2++];
}else
}while (p1 <= middle)
while (p2 <= right)
for ( i = 0;i < help.length;i++)
}
執行結果:
逆序對列印
和小和問題是同樣的套路,時間複雜度為o(n * log n),空間複雜度為o(n)
演算法初級筆記(一)認識時間複雜度
宣告 本筆記所涉及的資料 於牛客網常數時間的操作 乙個操作如果和資料量沒有關係,每次都是固定時間內完成的操作,叫做常數操作。我的理解是這種操作最終的執行就是執行彙編命令,而彙編命令執行花費的時間都是有限的機器時鐘時間,可以簡單理解為執行乙個相加指令,所以常數操作花費的時間是確定有限的,和數量級沒關係...
演算法時間複雜度的計算(初級)
在進行演算法分析時,語句總的執行次數t n 是關於問題規模n的函式,進而分析t n 隨n的變化情況並確定t n 的數量級。演算法的時間複雜度,也就是演算法的時間度量,記作 t n o f n 它表示隨問題規模n的增大,演算法執行時間的增長率和f n 的增長率相同,稱作演算法的漸近時間複雜度,簡稱為時...
演算法時間複雜度 一
演算法時間複雜度的定義 在進行演算法分析時,語句總的執行次數t n 是關於問題規模n的函式,進而分析t n 隨n的變化情況並確定t n 的數量級。演算法的時間複雜度記作 t n o f n f n 是問題規模n的某個函式。執行次數 時間 如何分析乙個演算法的時間複雜度 o階推導法 用常數1取代執行時...