【重温经典】单词搜索II
方法1:朴素版DFS
int [ ] dx = { - 1 , 0 , 1 , 0 } ;
int [ ] dy = { 0 , 1 , 0 , - 1 } ;
int m, n;
List < String > res = new ArrayList < > ( ) ;
public List < String > findWords ( char [ ] [ ] board, String [ ] words) {
this . m = board. length;
this . n = board[ 0 ] . length;
for ( String word : words) {
if ( exist ( board, word) ) res. add ( word) ;
}
return res;
}
public boolean exist ( char [ ] [ ] board, String word) {
for ( int i = 0 ; i < m; i++ ) {
for ( int j = 0 ; j < n; j++ ) {
if ( board[ i] [ j] == word. charAt ( 0 ) && dfs ( word, board, i, j, 0 ) ) return true ;
}
}
return false ;
}
private boolean dfs ( String word, char [ ] [ ] board, int i, int j, int idx) {
if ( i < 0 || i >= m || j < 0 || j >= n || board[ i] [ j] != word. charAt ( idx) )
return false ;
if ( idx == word. length ( ) - 1 ) return true ;
char t = board[ i] [ j] ;
board[ i] [ j] = '#' ;
for ( int d = 0 ; d < dx. length; d++ ) {
if ( dfs ( word, board, i + dx[ d] , j + dy[ d] , idx + 1 ) ) {
board[ i] [ j] = t;
return true ;
}
}
board[ i] [ j] = t;
return false ;
}
方法2:Trie+DFS
也可以用bool[m][n]
的访问数组标记某个字符的访问,替换掉board[i][j] = '#'
class TrieNode {
TrieNode [ ] next = new TrieNode [ 26 ] ;
String word;
}
int [ ] dx = { - 1 , 0 , 1 , 0 } ;
int [ ] dy = { 0 , 1 , 0 , - 1 } ;
int m, n;
List < String > res = new ArrayList < > ( ) ;
public List < String > findWords ( char [ ] [ ] board, String [ ] words) {
this . m = board. length;
this . n = board[ 0 ] . length;
TrieNode root = buildTrie ( words) ;
for ( int i = 0 ; i < m; i++ ) {
for ( int j = 0 ; j < n; j++ ) {
dfs ( board, i, j, root) ;
}
}
return res;
}
private void dfs ( char [ ] [ ] board, int i, int j, TrieNode p) {
if ( i < 0 || i >= m || j < 0 || j >= n) return ;
char c = board[ i] [ j] ;
if ( c == '#' || p. next[ c - 'a' ] == null ) return ;
p = p. next[ c - 'a' ] ;
if ( p. word != null ) {
res. add ( p. word) ;
p. word = null ;
}
board[ i] [ j] = '#' ;
for ( int d = 0 ; d < dx. length; d++ ) {
dfs ( board, i + dx[ d] , j + dy[ d] , p) ;
}
board[ i] [ j] = c;
}
private TrieNode buildTrie ( String [ ] words) {
TrieNode root = new TrieNode ( ) ;
for ( String word : words) {
TrieNode cur = root;
for ( char c : word. toCharArray ( ) ) {
if ( cur. next[ c - 'a' ] == null ) cur. next[ c - 'a' ] = new TrieNode ( ) ;
cur = cur. next[ c - 'a' ] ;
}
cur. word = word;
}
return root;
}
方法3:Trie板子+DFS
static class _4th {
class TrieNode {
public TrieNode [ ] next = new TrieNode [ 26 ] ;
public String word = "" ;
public TrieNode ( ) {
}
}
class Trie {
private TrieNode root;
public Trie ( ) {
root = new TrieNode ( ) ;
}
public void insert ( String word) {
TrieNode node = root;
for ( char c : word. toCharArray ( ) ) {
if ( node. next[ c - 'a' ] == null ) {
node. next[ c - 'a' ] = new TrieNode ( ) ;
}
node = node. next[ c - 'a' ] ;
}
node. word = word;
}
public boolean search ( String word) {
TrieNode node = root;
for ( char c : word. toCharArray ( ) ) {
if ( node. next[ c - 'a' ] == null ) return false ;
node = node. next[ c - 'a' ] ;
}
return node. word. equals ( word) ;
}
public boolean startsWith ( String prefix) {
TrieNode node = root;
for ( char c : prefix. toCharArray ( ) ) {
if ( node. next[ c - 'a' ] == null ) return false ;
node = node. next[ c - 'a' ] ;
}
return true ;
}
}
Set < String > res = new HashSet < String > ( ) ;
int m, n;
int [ ] dx = { - 1 , 0 , 1 , 0 } ;
int [ ] dy = { 0 , 1 , 0 , - 1 } ;
public List < String > findWords ( char [ ] [ ] board, String [ ] words) {
Trie trie = new Trie ( ) ;
for ( String word : words) {
trie. insert ( word) ;
}
m = board. length;
n = board[ 0 ] . length;
boolean [ ] [ ] visited = new boolean [ m] [ n] ;
for ( int i = 0 ; i < m; i++ ) {
for ( int j = 0 ; j < n; j++ ) {
dfs ( board, visited, "" , i, j, trie) ;
}
}
return new ArrayList < > ( res) ;
}
public void dfs ( char [ ] [ ] board, boolean [ ] [ ] visited, String str, int x, int y, Trie trie) {
if ( x < 0 || x >= m || y < 0 || y >= n) return ;
if ( visited[ x] [ y] ) return ;
str += board[ x] [ y] ;
if ( ! trie. startsWith ( str) ) return ;
if ( trie. search ( str) ) {
res. add ( str) ;
}
visited[ x] [ y] = true ;
for ( int d = 0 ; d < dx. length; d++ ) {
dfs ( board, visited, str, x + dx[ d] , y + dy[ d] , trie) ;
}
visited[ x] [ y] = false ;
}
}