题目79:
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
Example:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
分析:
class Solution {
public boolean exist(char[][] board, String word) {
//采用dfs遍历
char [] chs=word.toCharArray();
boolean [][] mark=new boolean[board.length][board[0].length];
for(int i=0;i<board.length;i++){
for(int j=0;j<board[0].length;j++){
if(dfs(board,i,j,0,chs,mark)){
return true;
}
}
}
return false;
}
public boolean dfs(char [][]board,int i,int j,int index,char [] chs,boolean [][] mark){
if(i<0||i>=board.length||j<0||j>=board[i].length||board[i][j]!=chs[index]||mark[i][j]){
return false;
}
//说明查找到相同的
if(index==chs.length-1){
return true;
}
//标志位置为true
mark[i][j]=true;
//回溯
if(dfs(board,i+1,j,index+1,chs,mark)||dfs(board,i-1,j,index+1,chs,mark)||dfs(board,i,j-1,index+1,chs,mark)||dfs(board,i,j+1,index+1,chs,mark)){
return true;
}
//标志位置为false
mark[i][j]=false;
//返回结果
return false;
}
}
题目212:
Given a 2D board and a list of words from the dictionary, find all words in the board.
Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
For example,
Given words = ["oath","pea","eat","rain"]
and board =
[ ['o','a','a','n'], ['e','t','a','e'], ['i','h','k','r'], ['i','f','l','v'] ]Return
["eat","oath"]
.
Note:
You may assume that all inputs are consist of lowercase letters a-z
.
分析:
class TrieNode{
//用来存储对应的单词后面的后续单词数组
TrieNode [] next=new TrieNode[26];
//存在在该位置上的单词完整体
String word;
}
public class Solution {
public List<String> findWords(char[][] board, String[] words) {
//采用dfs遍历,对于每个字符进行四个方向的搜索
//思路:使用回溯backtrace和dfs进行遍历,同时将单词表建立字典序
//将单词表放入矩阵中,之后回溯矩阵,路径中遍历到了单词完整体就加入结果
List<String> list=new ArrayList<>();
TrieNode root=buildTrie(words);
//对矩阵进行回溯
for(int i=0;i<board.length;i++){
for(int j=0;j<board[0].length;j++){
dfs(board,i,j,root,list);
}
}
return list;
}
//回溯
public void dfs(char[][] board,int i,int j,TrieNode root,List<String> list){
//出口
char c=board[i][j];
if(c=='#'||root.next[c-'a']==null){
return ;
}
root=root.next[c-'a'];//该字符的下一个
if(root.word!=null){
//说明存在一个单词在该路径上,
list.add(root.word);
//为了防止该单词重复计算,将其置null
root.word=null;
}
//该字符位置更换为#,表明其已经访问了
board[i][j]='#';
//回溯其四周
//上
if(i>0){
dfs(board,i-1,j,root,list);
}
//左
if(j>0){
dfs(board,i,j-1,root,list);
}
//下
if(i<board.length-1){
dfs(board,i+1,j,root,list);
}
//右
if(j<board[i].length-1){
dfs(board,i,j+1,root,list);
}
//将当前字符还原原来的字符
board[i][j]=c;
}
//建字典序
public TrieNode buildTrie(String [] words){
TrieNode root=new TrieNode();
if(words==null||words.length==0) return root;
for(String word:words){
TrieNode node=root;
//对每个单词输入字典序
for(char c:word.toCharArray()){
if(node.next[c-'a']==null){
node.next[c-'a']=new TrieNode();
}
//node继续下一个
node=node.next[c-'a'];
}
//字典序建立完成,将完整单词赋给最后一个位置
node.word=word;
}
return root;
}
}