C1增長率漸近分析,C2 遞迴和回溯
阿新 • • 發佈:2021-01-27
技術標籤:求職
C1
增長率
所謂增長率是指隨著輸入規模的增加,演算法執行時間增加的速度。
常用增長率:
不同增長率之間的關係
演算法分析有三種類型
- 最壞情況
- 最好情況
- 平均情況
大表示法:給出了函式的嚴格上限。(也可以說是最壞情況,或者直接用最高次項表示)
漸近分析指南
一層迴圈為嵌套了多少層就是的多少次方。
對數級時間複雜度:如果演算法可以在常數時間內把問題的規模按照某個分數分解,那麼該演算法的時間複雜度為, 典型例子為二分查詢。
例子1:下面函式執行的時間複雜度是多少?
void Function (int n) { int i=1 s=1; while(s<=n){ i++; s = s+i; System.out.println("*"); } }
注意s其實是i的累加 ,假設函式迭代次數是k 那麼:
例子2:下面函式執行的時間複雜度是多少?
void Function(int n){
int i,count=0;
for(i=1;i*i<=n;i++){
count++;
}
}
慣性思維! 這題不要累加,
例子3:下面函式執行的時間複雜度是多少?
void Function(int n){ int i,j,k,count=0; // n/2 次 for (i=n/2;i<=n;i++) // n/2 次 for (j=1;j+n/2<=n;j=j++) // logn 次 for (k=1;k<=n;k=k*2) count++; }
把n當作常數,依次用n表示每個迴圈的次數,相乘即可。
例子4:下面函式執行的時間複雜度是多少?(分治法一定要寫出遞推公式分析)
int Function(int n){
if (n==0){
return 0;
} else if (n==1){
return 1;
}else {
return Function(n-1) + Function(n-2);
}
}
遞推公式為:
有兩次遞迴呼叫,可表示為一顆二叉樹。每次遞迴呼叫,輸入規模分別減少1和2,所以遞迴樹的深度是
分治演算法主定理的計算和推倒筆記 :https://www.cnblogs.com/bush2582/p/13237409.html
C2
遞迴
遞迴和迭代(迴圈),
遞迴演算法經典用例
- 斐波那契數列,階乘
- 歸併排序,快速排序
- 二分查詢
- 數的遍歷和許多數的問題
- 圖的遍歷:深度優先搜尋,廣度優先搜尋
- 動態規劃
- 分治演算法
- 漢諾塔
- 回溯演算法
漢諾塔問題(這裡注意一下我的思維受到可預想的三個餅的情況影響,其實一個餅就可以作為基準情況)
static void TowersOfHanoi(int n, char frompeg, char topeg, char auxpeg) {
if (n==1) {
System.out.println("move disk 1 from " + frompeg + " to " + topeg);
return;
}
TowersOfHanoi(n-1,frompeg,auxpeg,topeg);
TowersOfHanoi(1,frompeg,topeg,auxpeg);
TowersOfHanoi(n-1,auxpeg,topeg,frompeg);
}
給定一個數組,用遞迴的方法判斷陣列中的元素是否是有正序的
static int isArrayInSortedOrder(int[] A, int index) {
if (index == 1) return 1;
return (A[index - 1] <= A[index - 2]) ? 0 : isArrayInSortedOrder(A, index - 1);
}
回溯
概念:一種採用分治策略進行窮舉搜尋的方法。
回溯演算法經典用例:
- 二進位制串,產生所有的二進位制串
- 生成K進位制串
- 揹包問題
- 廣義字串
- 哈密頓迴路
- 圖著色問題
回溯相關問題
生成所有位長的進位制字串。
public static char[] A = {'0','0','0','0','0','0'};
static void Binary(int n,int k) {
if (n < 1) {
for (char c : A) {
System.out.print(c+",");
}
System.out.println("");
}else {
for (int i=0;i<k;i++){
A[n-1] = String.valueOf(i).charAt(0); // int 轉 Char
Binary(n-1,k);
}
}
}