1. 程式人生 > 其它 >C1增長率漸近分析,C2 遞迴和回溯

C1增長率漸近分析,C2 遞迴和回溯

技術標籤:求職

C1

增長率

所謂增長率是指隨著輸入規模的增加,演算法執行時間增加的速度。

常用增長率:

不同增長率之間的關係

演算法分析有三種類型

  • 最壞情況
  • 最好情況
  • 平均情況

O表示法:給出了函式f(x)的嚴格上限。(也可以說是最壞情況,或者直接用最高次項表示)

漸近分析指南

一層迴圈為O(n)嵌套了多少層就是n的多少次方。

對數級時間複雜度:如果演算法可以在常數時間內把問題的規模按照某個分數分解,那麼該演算法的時間複雜度為O(logn), 典型例子為二分查詢。

例子1:下面函式執行的時間複雜度是多少?

void Function (int n) {
    int i=1 s=1;
    while(s<=n){
       i++;
       s = s+i;
       System.out.println("*");
    }
}

注意s其實是i的累加 ,假設函式迭代次數是k 那麼:1+2+...+k=\frac{k(k+1)}{2}>n\Rightarrow k=O(\sqrt{n})

例子2:下面函式執行的時間複雜度是多少?

   void Function(int n){
        int i,count=0;
        for(i=1;i*i<=n;i++){
            count++;
        }
    }

慣性思維! 這題不要累加,i^2\leq n\Rightarrow O(n)

例子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表示每個迴圈的次數,相乘即可。O(n^2logn)

例子4:下面函式執行的時間複雜度是多少?(分治法一定要寫出遞推公式分析)

     int Function(int n){
        if (n==0){
            return 0;
        } else if (n==1){
            return 1;
        }else {
            return Function(n-1) + Function(n-2);   
        }
    }

遞推公式為:T(n)=T(n-1)+T(n-2)+c

T(n)有兩次遞迴呼叫,可表示為一顆二叉樹。每次遞迴呼叫,輸入規模分別減少1和2,所以遞迴樹的深度是O(n)

。由於這是一顆滿二叉樹,所以深度為n的葉子節點的個數是2^n,每個葉子節點花費O(1)的執行時間,所以最終執行時間是O(2^n)

分治演算法主定理的計算和推倒筆記 :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進位制串
  • 揹包問題
  • 廣義字串
  • 哈密頓迴路
  • 圖著色問題

回溯相關問題

生成所有n位長的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);
           }
        }
    }

C3