面試中常用的算法——遞歸、回溯

排序算法
冒泡排序/Bubble Sort
插入排序/Insertion Sort
歸併排序/Merge Sort
快速排序/Quick Sort
拓撲排序/Topological Sort

遞歸和回溯/Recursion & Backtracking

遞歸的基本性質:函數調用本身
把大規模的問題不斷地變小,再進行推導的過程

回溯:利用遞歸的性質
從問題的起始點出發,不斷嘗試
返回一步甚至多步再做選擇,直到抵達終點的過程

遞歸

遞歸算法是一種調用自身函數的算法
特點:樂意使一個看似複雜的問題變得簡潔和易於理解
經典案例:漢諾塔(又稱河內塔)

遞歸的算法思想
要懂得如何將一個問題的規模變小
再利用從小規模問題中得出的結果
結合當前的值或者情況,得出最終的結果

通俗理解(自頂向下算法)
把要實現的遞歸函數,看成已經實現好的
直接利用解決一些子問題
思考:如何根據子問題的解以及當前面對的情況得出答案

遞歸寫法結構總結

function fn(n)
{
 //第一步:判斷輸入或者狀態是否非法
 if (input/state is valid)
 {
  return;
 }
 //第二步:判斷遞歸是否應當結束
 if (match condition)
 {
  return some value;
 }
 //第三步:縮小問題規模
 result1 = fn(n1);
 result2 = fn(n2);
 //第四步:整合結果
 return combine(result1, result2)
}

兩種遞歸算法解決時間複雜度分析
迭代法
公式法

迭代法
以漢諾塔問題爲例

void hano(char A, char B, char C, int n)
{
 if (n>0)
 {
  hano(A, C, B, n - 1);
  move(A, C);
  hano(B, A, C, n - 1);
 }
}

時間複雜度分析
if判斷語句:O(1)
move語句:O(1)
hano(A, C, B, n-1):T(n-1)
hano(B,A,C,n-1):T(n-1)
總的時間複雜度
T(n)= 1+2*T(n-1)+1=2T(n-1)+O(1)

當n=0時,T(n)=1。因爲當沒有盤子時,程序在if語句也要執行一次,判斷一下n是否大於0
最後得到的結果爲T(n)=2^n (2的n次方)

有時很難通過迭代法推導出比較複雜的時間複雜度,可以借用公式法。

公式法
公式法是計算遞歸函數複雜度最方便的工具。
只需要牢記3種可能會出現的情況以及處理他們的公式即可

當遞歸函數的時間執行函數滿足如下的關係式時,可以利用公式法:

在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

對於時間複雜度的分析是算法面試中非常重要的一環,掌握好迭代法和公式法對於分析大多數面試題都有非常重要的幫助。

**

**

回溯

回溯算法是一種試探算法,與暴力搜索最大的區別:
在回溯算法中,是一步步向前試探,對每一步探測的情況評估,再決定是否繼續,可避免走彎路

回溯算法的精華
出現非法的情況時,可退到之前的情景,可返回一步或多步
再去嘗試別的路徑和辦法
想要採用回溯算法,就必須保證:每次都有多種嘗試的可能。

回溯法解決問題的套路

function fn(n)
{
 //第一步:判斷輸入或者狀態是否非法
 if (input/state is invalid)
 {
  return;
 }
 //第二步:判斷遞歸是否應當結束
 if (match condition)
 {
  return some value;
 }
 //遍歷所有可能出現的情況
 for (all possible cases)
 {
  //第三步: 嘗試下一步的可能性
  Solutoin.push(case);
  //遞歸
  result = fn(m);
  //第四步:回溯到上一步
  Solution.pop(case)
 }
}

回溯其實是用遞歸實現的
因此在分析回溯的時間複雜度時,其實就是在對遞歸函數進行分析

分析一下N皇后的事假複雜度
假設backtracking 函數的執行時間是T(n)

  1. 首先每次都必須遍歷所有的列,這裏一共有n列
    a. 先要利用check函數檢查當前的擺放方法會不會衝突
    b. 檢查的時間複雜度由當前所在的行決定
    c. 但其上限是n,即需要檢查n行所以這裏的總時間複雜度就是O(n2)

  2. 接下來,遞歸地嘗試着每種擺放
    a. 當放好了第1個皇后,接下來要處理之後的n-1個皇后
    b. 問題的規模減少了一個,於是執行時間變成了T(n-1)

  3. 最終得到T(n)的表達式: T(n)=n*T(n-1) +O(n^2)

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章