件名の説明:
単語がグリッドに存在するかどうかを調べるために、二次元のグリッドと言葉を与えられました。
単語、隣接するセル内の文字のアルファベット順に構成する必要があり、水平方向または垂直方向に隣接するセルに隣接している「隣接」セル。同じセル内の文字を再利用することを許可されていません。
例:
ボード=
[
[ 'A'、 'B'、 'C'、 'E']、
[ 'S'、 'F'、 'C'、 'S']、
[ 'A'、 'D'、E ' 」、 'E']
]
与えられた単語= "ABCCEDは"、trueを返します。
単語= "SEE"を考えると、trueを返します。
単語= "ABCB"を考えると、falseを返します。
問題解決のアイデア:
そして、バックトラック深さ優先探索(DFS)
初版コード:
初版は、自分でバックトラッキングの考えを書かれましたが、DFSを理解したくありませんでした。特定のコード次のように、アイデアは、2次元アレイを横断する単語の最初の文字の位置を見つけ、その位置から、左誘惑、文字ダウンすることで、右位置単語の次の文字であればマッチングは、そうである場合、新しい開始位置としての位置は、単語の文字後退する再帰座標、及びワードパスと一致する場合、フラグと[I](0 <= iが<= 3)が記録されます。
配列のサイズが大きすぎて、単語の長さが長くなると、状況はあまりにも長く表示されます使用された場合であるとき、それはすべて、再びパス(ワード)長トラバーサルの2次元配列をlenをしますので、しかし、思考のこのラインは、タイムアウトになります。それでは、この道路や単語の一致、とはすぐにtrueを返した場合、それは、1つの道を行く必要があり、アップ他の経路を検討する必要はありません。
クラスソリューション{ パブリックブールは、(存在するcharが[] []ボード、文字列の単語を){ 場合(ボード== NULL || board.length == 0 ) を返す 偽。 以下のために(int型 i = 0 ; iはboard.length <; iは++ ){ ための(int型 J = 0 ; J <ボード[ 0 ] .LENGTH; J ++ ){ 場合(word.charAt(0)== ボード[I] [ J]){
int型 [] []マーク= 新しい INT ] [board.lengthを[ボード[0 ] .LENGTH]。 マーク[I] [J] = 1 。 もし(FUNC(ボード、単語、1 、I、J、マーク)) を返す 真。 } } } を返す 偽。 } パブリックブールFUNC(CHAR [] []ボード、文字列の単語、int型の POS、int型の行、INT COL、INT [] []マーク){ 場合(posが== word.length())を返す 真。 ブール[]フラグ= 新しいブール[ 4 ]。 もし(行> 0 &&マーク[行優先1 ] [COL] == 0 ){ 場合(ボード[行優先1 ] [COL] == word.charAt(POS)){ マーク[行 - 1 ] [COL] = 1 ; フラグ[ 0 ] =のFUNC(ボード、単語、POS + 1、行優先1 、COL、マーク)。 マーク[行 - 1 ] [COL] = 0 ; } } もし(行<board.length- 1&&マーク[行+ 1 ] [COL] == 0 ){ 場合(ボード[行+ 1 ] [COL] == word.charAt(POS)){ マーク[行 + 1 ] [COL] = 1 。 フラグ[ 1 ] FUNC(ボード、単語、POS + = 1、行+ 1 、COL、マーク)。 マーク[行 + 1 ] [COL] = 0 ; } } もし(COL> 0 &&マーク[行] [col- 1 ] == 0 ){ もし(ボード[行] [COL - 1 ] == word.charAt(POS)){ マーク[行] [COL - 1 ] = 1 。 フラグ[ 2 ] FUNC(ボード、単語、POS + = 1、行、col- 1 、マーク)。 マーク[行] [COL - 1 ] = 0 ; } } もし(COL <ボード[ 0 ] .length- 1 &&マーク[行] [COL + 1 ] == 0 ){ 場合(ボード[行] [COL + 1 ] == word.charAt(POS)){ マーク[行] [COL+ 1 ] = 1 。 フラグ[ 3 ] FUNC(ボード、単語、POS + = 1、行、列+ 1 、マーク)。 マーク[行] [COL + 1 ] = 0 ; } } 場合(フラグ[ 0 ] ||フラグ[ 1 ] ||フラグ[ 2 ] ||フラグ[ 3 ]) を返す 真。 返す 偽; } }
Second Editionのコード:
上記のコードの最初のバージョンでは説明を読んだ後に変更され、DFSのアイデアは[]このフラグのフラグに除去し、添加し、単語がこのパスに一致する場合、直接返します
パブリック ブール(存在CHAR [] []ボード、文字列の単語){ 場合(ボードは== NULL || board.lengthが== 0 ) を返す 偽。 以下のために(int型 i = 0; iはboard.length <; iは++ ){ ための(int型 J = 0; J <ボード[0] .LENGTH; J ++ ){ 場合(word.charAt(0)== ボード[I] [ J]){ // 记录该位置是否已经通过 のint [] []マーク= 新しい INT [board.length] [ボード[0 ] .LENGTH]。 マーク[I] [J] = 1; もし(FUNC(ボード、単語、1 、I、J、マーク)) を返す 真。 } } } を返す 偽。 } パブリック ブール FUNC(CHAR [] []ボード、文字列の単語、int型の POS、int型の行、INT COL、INT [] []マーク){ 場合(posが== word.length())を返す 真。 ブール []フラグ= 新しい ブール [4 ]。 もし(行> 0 &&マーク[行1] [COL] == 0 ){ 場合(ボード[行1] [COL] == word.charAt(POS)){ マーク[行 -1] [COL] = 1 ; // 递归 場合(FUNC(ボード、単語、POS + 1、行1 、列、マーク)) を返す 真。 // 回溯 マーク[行1] [COL] = 0 ; } } もし(行<board.length-1 &&マーク[行+ 1] [COL] == 0 ){ 場合(ボード[行+ 1] [COL] == word.charAt(POS)){ マーク[行 +1] [COL] = 1; もし(FUNC(ボード、単語、POS + 1、行+ 1 、COL、マーク)) を返す 真。 マーク【行 +1] [COL] = 0 ; } } もし(COL> 0 &&マーク[行] [COL-1] == 0 ){ 場合(ボード[行] [COL - 1] == word.charAt(POS)){ マーク[行] [COL - 1] = 1 。 もし(FUNC(ボード、単語、POS + 1、行、COL-1 、マーク)) を返す 真。 マーク[行] [COL -1] = 0 ; } } であれば(COL <ボード[0] .LENGTH-1 &&マーク[行] [COL + 1] == 0 ){ 場合(ボード[行] [COL + 1] == word.charAt(POS)){ マーク[行] [COL +1] = 1 。 もし(FUNC(ボード、単語、POS + 1、行、列+ 1 、マーク)) を返す 真。 マーク[行] [COL +1] = 0 ; } } を返す 偽。 }