leetcode212--网格搜索单词

  1. 字典树
  2. 回溯
  3. 剪枝
class Solution {
    int[] dx = {0, 0, -1, 1};
    int[] dy = {-1, 1, 0, 0};
    boolean[][] visited = null;
    List<String > result = new ArrayList<>();
    public List<String> findWords(char[][] board, String[] words) {
        TrieTree trieTree=initTrie(words);

        visited = new boolean[board.length][board[0].length];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                // System.out.println("新起点:"+i+j);
                backtrack(i, j, board, board[i][j]+"",trieTree.root);

            }
        }
        return result;
//        return backtrack(0,0,board,"",word);
    }

    private TrieTree initTrie(String[] words) {
        TrieTree trieTree = new TrieTree();
        TrieTree.Node root = new TrieTree.Node();
        trieTree.setRoot(root);
        for (int i = 0; i < words.length; i++) {
            TrieTree.Node start = root;
            for (int j = 0; j < words[i].length(); j++) {
                char ij = words[i].charAt(j);
                // System.out.println("构造:"+ij);
                if (start.getNext().get(ij) == null) {
                    // System.out.println("不存在,构造增加:"+ij);

                    start.getNext().put(ij, new TrieTree.Node());
                }
                // System.out.println("存在,下一个:"+ij);
                start = start.getNext().get(ij);
            }
            start.setEnd(true);
            start.setWord(words[i]);
        }
        return trieTree;
    }

    public void backtrack(int i, int j, char[][] board, String res, TrieTree.Node trieTree) {

Character letter = board[i][j];
        TrieTree.Node currNode = trieTree.getNext().get(letter);
        if (currNode!=null&&currNode.isEnd()) {
            if (!result.contains(currNode.word)){

            result.add(currNode.word);
            }
        }
        // System.out.println("back:"+board[i][j]+"--"+res);
        if (trieTree.getNext().containsKey(board[i][j])) {
            visited[i][j] = true;
            for (int k = 0; k < dx.length; k++) {
                int tempi = i + dx[k];
                int tempj = j + dy[k];
                //  System.out.println("dfs"+tempi+","+tempj);
                if ((tempi >= 0 && tempj >= 0 && tempi < board.length && tempj < board[0].length) && !visited[tempi][tempj]) {


                    backtrack(tempi, tempj, board, res+board[tempi][tempj],  currNode);
//                        return true;
//                    }
                }
            }
            // System.out.println("没找到"+board[i][j]+"--"+res);
            visited[i][j] = false;
            if (currNode.getNext().isEmpty()) {
                trieTree.getNext().remove(letter);
            }
//            backtrack(i+dx[1],j+dy[1],board,res+board[i+dx[1]][j+dy[1]],word);
//            backtrack(i+dx[2],j+dy[2],board,res+board[i+dx[2]][j+dy[2]],word);
//            backtrack(i+dx[3],j+dy[3],board,res+board[i+dx[3]][j+dy[3]],word);
        }
        return ;
    }

    public static class TrieTree {

        public Node getRoot() {
            return root;
        }

        public void setRoot(Node root) {
            this.root = root;
        }

        Node root;

        public boolean has(String res){
            Node lastNode=root;
            for (int i = 0; i < res.length(); i++) {
               lastNode =lastNode.getNext().get(res.charAt(i));
                if (null==lastNode){
                    return false;
                }
            }
            return lastNode.isEnd();
        }
        public boolean startWith(String res){
            Node lastNode=root;
            for (int i = 0; i < res.length(); i++) {
               lastNode =lastNode.getNext().get(res.charAt(i));
                if (null==lastNode){
                    return false;
                }
            }
            return true;
        }

        public static class Node {
            public Node() {

            }

            public Node(char value, boolean isEnd) {
                this.value = value;
                this.isEnd = isEnd;
            }

            Map<Character, Node> next = new HashMap<>();
            char value;
            boolean isEnd;

            public String getWord() {
                return word;
            }

            public void setWord(String word) {
                this.word = word;
            }

            String word;

            public Map<Character, Node> getNext() {
                return next;
            }

            public void setNext(Map<Character, Node> next) {
                this.next = next;
            }

            public char getValue() {
                return value;
            }

            public void setValue(char value) {
                this.value = value;
            }

            public boolean isEnd() {
                return isEnd;
            }

            public void setEnd(boolean end) {
                isEnd = end;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值