单词搜索 II

给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。

示例:

输入: 
words = ["oath","pea","eat","rain"] and board =
[
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]

输出: ["eat","oath"]

思路:

1、要打印所有情况,因此进行dfs,单词不允许重复,使用Set存储结果

2、将字典词存到字典树中

3、以二维数组每一个元素为单词第一个字母去遍历字典树,二维数组中的延伸方向为上下左右,使用visit数组保存是否访问过节点,使用数组边界判断避免越界

4、在dfs过程中判断单词所在字典树的节点end属性是否为true,为true添加该节点,继续dfs

5、dfs结束条件为树节点为null,返回false;

class Solution {
    //构建trie树节点
    public class TrieNode{
        private Map<Character,TrieNode> map = new HashMap<>();
        private boolean end;
        public TrieNode getSubNode(Character key){
            return map.get(key);
        }
        public void addSubNode(Character key,TrieNode value){
            map.put(key,value);
        }
        public boolean containsNode(Character key){
            return map.containsKey(key);
        }
        public boolean isEnd(){
            return end;
        }
        public void setEnd(boolean end){
            this.end=end;
        }
    }
    
    public List<String> findWords(char[][] board, String[] words) {
        TrieNode root=new TrieNode();
        root = insertWord(root,words);
        List<String> list = new ArrayList<>();
        Set<String> set = new HashSet<>();
        StringBuilder sb = new StringBuilder();
        boolean[][] visit = new boolean[board.length][board[0].length];
        int count=0;
        for(int i=0;i<board.length;i++){
            for(int j=0;j<board[0].length;j++){  
                searchWords(i,j,root,board,set,sb,visit);
            }
        }
        
        for(String s:set){
            list.add(s);
        }
        
        
        return list;
    }
    //插入字典单词到trie树
    public TrieNode insertWord(TrieNode root,String[] words){
        TrieNode tmpNode = root;
        for(int i=0;i<words.length;i++){
            tmpNode=root;
            for(int j=0;j<words[i].length();j++){
                char c = words[i].charAt(j);
                
                TrieNode node = tmpNode.getSubNode(c);
                if(node==null){
                    node=new TrieNode();
                    tmpNode.addSubNode(c,node);
                }
                tmpNode=node;
                if(j==words[i].length()-1){tmpNode.setEnd(true);}
            }
            
        }
        return root;
    }
    
    public boolean searchWords(int i,int j,TrieNode node,char[][] board,Set<String> list,StringBuilder sb,boolean[][] visit){
        boolean success=false;
        TrieNode tmpNode = node.getSubNode(board[i][j]);
        if(tmpNode==null){
                return false;
        }else{
            sb.append(board[i][j]);
            visit[i][j]=true;
            
            if(tmpNode.isEnd()){
                list.add(new String(sb));
            }
            
            if((i>0&&!visit[i-1][j])&&!success){
                success=searchWords(i-1,j,tmpNode,board,list,sb,visit);
            }
            if((i<board.length-1&&!visit[i+1][j])&&!success){
                success=searchWords(i+1,j,tmpNode,board,list,sb,visit);
            }
            if((j>0&&!visit[i][j-1])&&!success){
                success=searchWords(i,j-1,tmpNode,board,list,sb,visit);
            }
            if((j<board[0].length-1&&!visit[i][j+1])&&!success){
                
                success=searchWords(i,j+1,tmpNode,board,list,sb,visit);
            }
            
            sb.delete(sb.length()-1,sb.length());
            visit[i][j]=false;

        }
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/y649014081/article/details/88562016
今日推荐