回溯法 N皇后與解數獨

2021-10-23 07:39:18 字數 2664 閱讀 5600

但中間也在用零碎的時間學學別的,今天寫總結一下回溯法。

在最壞的情況下,回溯法會導致一次複雜度為指數時間的計算。

回溯法實際上是一種 dfs(深度優先搜尋演算法)的一種,不同的是,回溯法具備剪枝的能力,下面通過兩個例子來具體分析回溯演算法。

n 皇后問題是基於八皇后問題的進一步發展,如何能夠在 n * n 大小的西洋棋棋盤上擺放 n 個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。下圖為八皇后問題的其中乙個解。

下面來分析下這個問題。

棋盤上每個位置包含兩種狀態:有皇后以及沒有皇后。在不考慮約束條件的情況下,列出所有組合,我們將得到乙個深度為 n * n 的二叉樹。

上圖描述了棋盤前兩個位置的可能性。

最簡單的辦法是窮舉出所有可能性,然後篩選出符合的解。可以通過 dfs 演算法遍歷這個二叉樹,對於 n * n 的棋盤將有 2 的 n * n 次方種可能,這顯然是不可接受的。

但我們可以通過規則來進行剪枝,可以使用的規則如下:

通過上述四個條件,我們可以減掉大部分的路徑。

現在回到回溯法上來看這道題,回溯法使用試錯的思想,分步解決問題,我們可以先假設第乙個位置放置皇后,然後根據規則,找到第二個合法的位置再放置第二個皇后,如果找不到合適的位置則表示該路徑錯誤,回溯到上乙個位置繼續。

回溯法特徵之一就是會使用陣列或其他資料結構儲存遍歷資訊,從而跳過不合法的路徑。

本題使用三個陣列分別儲存列、左上至右下斜邊、右上至坐下斜邊的皇后擺放資料。

因為每行只能擺放乙個皇后,所以我們按行遍歷,嘗試在當前行每乙個位置放置皇后。然後跳到下一行繼續。

下面直接放上**:

public list

>

solvenqueens

(int n)

private

void

backtrace

(int n,

int row,

boolean

column,

boolean

rl,boolean

lr,int[

] board, list

> result)

boardlist.

add(rowbuilder.

tostring()

);} result.

add(boardlist);}

//for

(int columnindex =

0; columnindex < n; columnindex++)}

}

數獨遊戲就是我們常見的那個解數獨的遊戲。

思路跟 n 皇后一樣,遍歷所有空格,逐個將 1-9 陣列放置空格內,通過規則判斷是否合法,最終找到解。

這裡同樣需要定義三個陣列用於存放遍歷資料:每行、每列、每 3x3 宮格內的資料。

另外,如果 sn 表示 第 n 個 3x3 宮格,那麼 sn = (row / 3) * 3 + column / 3;

public

void

solvesudoku

(char

board)

if(columnrecord[column]

== null)

int boxindex =

(row /3)

*3+ column /3;

if(boxrecord[boxindex]

== null)

if(c !=

'.')}}

backtrack

(board,0,

0, rowrecord, columnrecord, boxrecord);}

private

boolean

backtrack

(char

board,

int row,

int column,

list

rowrecord,

list

columnrecord,

list

boxrecord)

int nextrow = column <

8? row : row +1;

int nextcolumn = column <

8? column +1:

0;int boxindex =

(row /3)

*3+ column /3;

character currentchar = board[row]

[column];if

(currentchar ==

'.')

else}}

}else

return

false

;}

上面的**我放在 github 上了,裡面還有很多其他資料結構與演算法相關的**,需要的可以看看:

回溯法解數獨

前天在我的小pad上裝了個數獨遊戲,完了幾把後興趣索然了。不過突然想起來一直想寫個解數獨的程式,不過因為懶和拖拉,就一直沒寫。今天花了30分鐘寫了個解數獨的程式,貼 include include include 某個數字填入後,需要檢查的index void get affected index ...

leetcode 解數獨 回溯法

如 方法 回溯法 回溯法的思想就是 對於乙個問題有多個選擇方式,先選擇乙個方式執行下去,若在執行過程中,發現不符合規則,則回退,回到選擇方式的步驟,進而選擇其他方式,繼續試。重要 對於回溯法,一定會有個 規則 這個 規則 將會決定是否回退,所以當我們在使用回溯法時,一定要留意能否構建 規則 如這一題...

N 皇后問題 回溯法

n 皇后問題 在 n n 的棋盤上放置彼此不受攻擊的 n 個皇后,任意兩個皇后不同行 不同列 不同斜線。思路 1.因為皇后不能同行,所以,在每一行放置乙個皇后就行 2.當在一行放置皇后的時候 1 順序檢查這一行每乙個位置是否和上面所有的皇后,只要有乙個同列或者在斜線上就不能放置 若找到乙個滿足的,放...