Leetcode - Word Search II

https://leetcode.com/problems/word-search-ii/description/

这一题,如果不懂原理想必会很麻烦,但是如果知道用trie tree做,就不值得一个hard。

这一题就是很纯粹的trie tree + dfs,为了避免dfs过度的延伸,我们在这里利用到了trie tree的截枝功能。如果这里利用HashSet<String>作为节点,那么你只能判断什么时候成功,但是你势必每个dfs要走完全图,不会知道什么时候是一个false终止的信号。这样的超级大指数级别的performance肯定不是我们想要的。这个就是trie tree能够给你的,一个个字符和子节点的匹配,可以有很有效率的进行dfs遍历的终结。还需要说什么的话就是大部分类似题目的inplace 记录走过的节点啊,之类的。。直接给出代码吧

    class TrieNode {
        boolean isWord;
        TrieNode[] children;
        public TrieNode() {
            this.isWord = false;
            this.children = new TrieNode[26];
        }
    }

    class TrieTree {
        TrieNode root;
        
        public TrieTree() {
            root = new TrieNode();
        }
        
        public void addWord(String word) {
            TrieNode current = root;
            for (int i = 0; i < word.length(); i++) {
                int index = word.charAt(i) - 'a';
                if (current.children[index] == null) {
                    current.children[index] = new TrieNode();
                }
                current = current.children[index];
            }
            current.isWord = true;
        }
    }
    
    public List<String> findWords(char[][] board, String[] words) {
        TrieTree dict = new TrieTree();
        for (String word : words) dict.addWord(word);
        
        Set<String> resSet = new HashSet<String>();
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                Set<String> curResSet = _DFSFindWords(board, i, j, new StringBuilder(), dict.root);
                if (curResSet != null) resSet.addAll(curResSet);
            }
        }
        
        return new LinkedList<String>(resSet);
    }
    
    static int[][] DIR = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    
    private Set<String> _DFSFindWords(char[][] board, int x, int y, StringBuilder sb, TrieNode curNode) {
        if (x < 0 || x >= board.length || y < 0 || y >= board[0].length || board[x][y] == '-') {
            return null;
        } else {
            char c = board[x][y];
            int index = c - 'a';
            if (curNode.children[index] == null) {
                return null;
            } else {
                Set<String> curRes = new HashSet<String>();
                sb.append(c);
                if (curNode.children[index].isWord) {
                    curRes.add(sb.toString());
                }

                board[x][y] = '-';
                for (int[] dir : DIR) {
                    Set<String> nextRes = _DFSFindWords(board, x + dir[0], y + dir[1], sb, curNode.children[index]);
                    if (nextRes != null) {
                        curRes.addAll(nextRes);
                    }
                }
                board[x][y] = c;
                sb.deleteCharAt(sb.length() - 1);
                return curRes;
            }
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值