經典演算法之回溯法

2021-08-04 20:14:18 字數 2049 閱讀 1045

1 綜述

回溯法可以看成是蠻力法的公升級版,它從解決問題每一步的所有可能選項裡系統的選擇出乙個可行的解決方案。回溯法非常適合由多個步驟組成的問題,並且每個步驟都有多個選項。當我們在某一步選擇了其中乙個選項時,就進入下一步,然後面臨新的選項。我們就這麼重複選擇,直至到達最終的狀態。

用回溯法解決的問題的所有選項可以形象地用樹狀結構表示。在某一步有n個可能的選項,那麼該步驟可以看成是樹狀結構中的乙個節點,每個選項看成樹中節點的連線線,經過這些連線線到達某個節點的n個子節點。樹的葉節點對應著終結狀態。如果在葉節點的狀態滿足題目的約束條件,那麼我們找到了乙個可行的解決方案。

如果在葉節點的狀態不滿足約束條件,那麼只好回溯到它的上乙個節點再嘗試其他選項。如果上乙個節點所有可能的選項都已經試過,並且不能達到滿足約束條件的終結狀態,則再次回溯到上乙個節點。如果所有節點的所有選項都已經嘗試過仍然不能到達滿足約束條件的終結狀態,則該問題無解。

2 演算法用法

當問題是要求滿足某種性質(約束條件)的所有解或最優解時,往往使用回溯法。所以它有「通用解題法」之美譽。

(1)裝載問題

(2)0-1揹包問題

(3)旅行售貨員問題

(4)八皇后問題

(5)迷宮問題

(6)圖的m著色問題

4 面試題:矩陣中的路徑

4.1 題目

請設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某字串的所有字元的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某個空格,那麼該路徑不能再次進入該格仔。例如,下面的3×4的矩陣中包含一條字串「bfce」的路徑,但是並不包含一條字串「abfe」路徑,因為第乙個字元b佔據了第一行第二列的格仔,路徑不能再次進入這個格仔。

——劍指offer面試題:12

a  b  t  g

c  f  c  s

j  d  e  h

4.2 分析

這是乙個經典的可以用回溯法解決的題。首先,我們從矩陣中任意乙個字元出發。假設矩陣中某個格仔的字元表示為char_one,並且這個格仔將對應於路徑上的第i個字元。如果路徑上的第i個字元不是char_one,那麼其就不該出現在路徑上第i個位置,需要退回上個狀態i-1重新尋找第i個字元。如果恰好就是第i個字元,那麼我們就可以在相鄰的格仔尋找路徑上第i+1個字元。矩陣除邊界上格仔外相鄰都是4個格仔。重複這個過程,直到路徑上的所有字元都能在矩陣中找到對應為重。整個過程又非常像棧資料結構的入棧與出棧操作。

4.3 **

#include 

#include

#include

using

namespace

std;

bool haspathcore(const

char* matrix, int rows, int cols, int row, int col, const

char* str, int& pathlength, bool* visited);

bool haspath(const

char* matrix, int rows, int cols, const

char* str)}}

delete visited;

return

false;

}bool haspathcore(const

char* matrix, int rows, int cols, int row,

int col, const

char* str, int& pathlength, bool* visited)

}return haspath;

}

——參考自劍指offer

4.4 測試

int main()

演算法入門6:回溯法

劍指offer

經典演算法之回溯法

回溯演算法實際上乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就 回溯 返回,嘗試別的路徑。回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,...

演算法之回溯法

回溯法非常適合由多個步驟組成的問題,並且每個步驟都有多個選項。當我們在某一步選擇了其中乙個選項時,就進入下一步,然後面臨新選項,重複選擇,直至最終狀態。經典面試題1 矩陣中的路徑 詳見 劍指offer 面試題12 易錯點 1.由於路徑不能重複進入矩陣的格仔,因此還需定義和字元矩陣大小一樣的布林值矩陣...

演算法之回溯法

求解步驟 1,定義給定問題的解向量解空間 子集樹 排列樹 2,設計剪支函式 限界函式及約束函式 3,深度優先遍歷結合剪支得出解 求解過程 1,是否為完全解,是則輸出 2,是否為部分解,是則進行下乙個解分量的判斷 3,是否為當前可選集合中的最後乙個元素,是則回溯,重新判斷上乙個節點,否則判斷可選集合中...