LeetCode.79(212)Word Search I && II

题目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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值