コンセプト
バックトラックは、実際に検索処理を列挙する同様の試みであり、主な問題は、別のパスを試すに戻る「戻る」で、条件が満たされていない解決されているがわかったときに、検索しようとする過程で解決策を見つけることです。
キーワードや語句
解空間の木、木、DFS
擬似コード
=結果[] DEFバックトラック(経路選択リスト): IF 条件の端は (パス)result.add 復帰 選択リストの選択のための 選択する // バイナリツリーの先行順走査に対応して バックトラック(パス選択リスト) 選択解除します/ / バイナリツリートラバーサルに対応する配列の後
ツリートラバーサル ボイドトラバース(ツリーノードルート){ ため(ツリーノードの子供:root.childern) // 予約限定トラバーサル所望の動作 トラバース(子); // 操作を必要と後順 }
典型的な例
完全な配列
パッケージバックトレース。 輸入はjava.util.ArrayList; 輸入はjava.util.List; // 求N的全排列 パブリック クラスPermutePrac { プライベートリスト<リスト<Integer型>> listList = 新しい ArrayListを<> (); 公衆リスト<リスト<整数>>並び替える(INT [] NUMS){ int型のlen = nums.length。 バックトラック(新しい ArrayListを<> ()、len は、NUMS)。 返すlistListを。 } パブリック 無効後戻り(一覧<整数>リスト、int型のn、int型[] NUMS){ // 判断回溯值 場合(はlist.size()== N){ listList.add(新規のArrayList <> (リスト))。 } // 遍历 ため(INT I = 0、I <N; I ++ ){ // 约束条件 場合(list.contains(NUMS [I]))は{ 続けます。 } list.add(NUMS [I])。 バックトラック(リスト、N、NUMS)。 // 回溯 list.remove(はlist.size() - 1 )。 } } }
八のクイーンズ
パッケージbacktracing.nqueen、 インポートjava.util.ArrayListのの、 インポートjava.util.Listに; // leetcode 51れる // // 整数nは、全ての異なる溶液クイーン問題nのリターンを考えます。 // // 各溶液は「Q」と「」とのギャップは女王を表すクイーン問題のプログラムに置か明示n個を含有します。 // // 例: // // 入力:4 // 出力:[ // [ ".Q .."、 // ソリューション1。 // "Q ..."、 // "Q ..."、 // "..Q。 "]、 // // [" ..Q。"、 // 方法2 // "Q ..."、 // ".Q .."] // ] パブリック クラスソリューション{ リスト <リスト<文字列>> listlist = 新しい ArrayListを<> (); 公衆リスト<リストの<string >> solveNQueens(INT N){ solveNQueenUtil( 0、N、新規のArrayList <> ()); リターンlistlist。 } プライベート ボイド solveNQueenUtil(int型の列、整数 nは、リストの<string> リスト){ 場合(行== N){ (listlist.add 新規のArrayList <>(リスト)); リターン; } のための(INT COL = 0、COL <N; COL ++ ){ list.add(generateColn(COL、N))。 もし(isSafe(リスト、N)){ solveNQueenUtil(行 + 1 、nは、リスト)。 } list.remove(はlist.size() - 1 )。 } } プライベートストリングgenerateColn(int型 COL、INT N){ StringBufferのSB = 新規のStringBuffer(); 以下のために(INT iが= 0、I <N; I ++){ もし(I == COL){ sb.append( "Q" )。 } 他{ sb.append( "" )。 } } を返す)(sb.toStringします。 } ブール isSafe(リストの<string>リスト、INT N){ リターン isColSafe(リスト、N)&& isLeftDiagnoseSafe(リスト、N)&& isRightDiagnoseSafe(リスト、N)。 } ブール isColSafe(リストの<string>リスト、INT N){ ため(INT COL = 0、COL <N; COL ++){ int型のカウント= 0 ; 用(INT、行<はlist.size();行= 0行++ ){ 場合(list.get(行).charAt(COL)== 'Q' ){ カウント ++ 。 } } もし(カウント> 1 ){ 戻り 偽。 } } 戻り 真。 } ブール isLeftDiagnoseSafe(リストの<string>リスト、INT N){ ため(INTCOL = 0; COL <N。COL ++ ){ int型 nextRow = 0 。 int型 nextCol = COL。 int型のカウント= 0 ; もし(leftDianoseUtil(リスト、nextRow、nextCol、カウント数))のリターン はfalse ; } のための(INT列= 0、行<はlist.size();行++ ){ int型 nextRow = 行。 INT nextCol = N - 1 。 int型のカウント= 0 ; もし(leftDianoseUtil(リスト、nextRow、nextCol、カウント数))のリターン 偽; } を返す 真。 } プライベート ブール leftDianoseUtil(リストの<string>リスト、INT nextRow、INT nextCol、INT カウント){ 一方(nextRow <はlist.size()&& nextCol> = 0 ){ 場合(list.get(nextRow).charAt(nextCol) == 'Q' ){ カウント ++ ; } nextCol - 。 nextRow ++ ; } であれば(カウント> 1 ){ リターン 真; } を返す 偽。 } ブール isRightDiagnoseSafe(リストの<string>リスト、INT N){ ため(INT COL = N - 1; COL> = 0; col-- ){ int型 nextRow = 0 。 int型 nextCol = COL。 int型のカウント= 0 ; もし(rightDianoseUtil(リスト、nは、nextRow、nextCol、カウント数))のリターン はfalse ; } のための(INT列= 0、行<はlist.size();行++ ){ int型nextRow = 行。 int型 nextCol = 0 ; int型のカウント= 0 ; もし(rightDianoseUtil(リスト、nは、nextRow、nextCol、カウント数))のリターン はfalse ; } を返す 真。 } プライベート ブール rightDianoseUtil(リストの<string>リスト、整数 nは、INT nextRow、INT nextCol、INT カウント){ 一方(nextRow <はlist.size()&& nextCol < N){ 場合(list.get(nextRow).charAt( nextCol)== 'Q' ){ カウント ++ ; } nextCol ++ 。 nextRow ++ ; } 場合(カウント> 1 ){ 戻り 真。 } を返す 偽。 } パブリック 静的 ボイドメイン(文字列[]引数){ 溶液溶液 = 新しいソリューション()。 solution.solveNQueens( 4 )。 System.out.println(solution.listlist)。 } }
参考文献:
1. https://leetcode-cn.com/problems/n-queens/solution/hui-su-suan-fa-xiang-jie-by-labuladong/(プライマリ参照)
2. https://leetcode-cn.com/problems/n-queens/solution/nhuang-hou-by-leetcode/