zoukankan      html  css  js  c++  java
  • Word Search II

    Word Search II

    问题:

    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.

    思路:

      回溯

    我的代码:

    public class Solution {
        private Trie trie = new Trie();
        private List<String> list = new ArrayList<String>();
        public List<String> findWords(char[][] board, String[] words) {
            if(board==null || board.length==0 || board[0].length ==0 || words==null || words.length==0)  return list;
            for(String word: words)        trie.insert(word);
            int row = board.length;
            int col = board[0].length;
            boolean[][] isVisited = new boolean[row][col];
            for(int i = 0; i < row; i++)
            {
                for(int j = 0; j < col; j++)
                {
                    if(trie.startsWith(String.valueOf(board[i][j])))
                    {
                        isVisited[i][j] = true;
                        helper(board, ""+board[i][j], i, j, isVisited, row, col);
                        isVisited[i][j] = false;
                    }
                }
            }
            return list;
        }
        public void helper(char[][] board, String word, int i, int j, boolean[][] isVisited, int row, int col)
        {
            if(trie.search(word))
            {
                if(!list.contains(word))    list.add(word);
            }
            //left
            if(j > 0 && isVisited[i][j-1] == false && trie.startsWith(word+board[i][j-1]))
            {
                isVisited[i][j-1] = true;
                helper(board, word+board[i][j-1], i, j-1, isVisited, row, col);
                isVisited[i][j-1] = false;
            }
            //right
            if(j < col - 1 && isVisited[i][j+1] == false && trie.startsWith(word+board[i][j+1]))
            {
                isVisited[i][j+1] = true;
                helper(board, word+board[i][j+1], i, j+1, isVisited, row, col);
                isVisited[i][j+1] = false;
            }
            //up
            if(i > 0 && isVisited[i-1][j] == false && trie.startsWith(word+board[i-1][j]))
            {
                isVisited[i-1][j] = true;
                helper(board, word+board[i-1][j], i-1, j, isVisited, row, col);
                isVisited[i-1][j] = false;
            }
            //down
            if(i < row-1 && isVisited[i+1][j] == false && trie.startsWith(word+board[i+1][j]))
            {
                isVisited[i+1][j] = true;
                helper(board, word+board[i+1][j], i+1, j, isVisited, row, col);
                isVisited[i+1][j] = false;
            }
        }
        class TrieNode {
            char c;
            boolean leaf;
            HashMap<Character, TrieNode> children = new HashMap<Character, TrieNode>();
            public TrieNode(char c) {
                this.c = c;
            }
            public TrieNode(){};
        }
    
        class Trie {
            private TrieNode root;
            public Trie() {
                root = new TrieNode();
            }
            public void insert(String word) {
                Map<Character, TrieNode> children = root.children;
                for(int i=0; i<word.length(); i++) {
                    char c = word.charAt(i);
                    TrieNode t;
                    if(children.containsKey(c)) {
                        t = children.get(c);
                    } else {
                        t = new TrieNode(c);
                        children.put(c, t);
                    }
                    children = t.children;
                    if(i==word.length()-1) t.leaf=true;
                }
            }
            public boolean search(String word) {
                TrieNode t = searchNode(word);
                return t!=null && t.leaf;
            }
            public boolean startsWith(String prefix) {
                return searchNode(prefix) != null;
            }
            
            private TrieNode searchNode(String word) {
                Map<Character, TrieNode> children = root.children;
                TrieNode t = null;
                for(int i=0; i<word.length(); i++) {
                    char c = word.charAt(i);
                    if(!children.containsKey(c)) return null;
                    t = children.get(c);
                    children = t.children;
                }
                return t;
            }
        }
    }
    View Code

    他人代码:

    ublic class Solution {
        Set<String> res = new HashSet<String>();
    
        public List<String> findWords(char[][] board, String[] words) {
            Trie trie = new Trie();
            for (String word : words) {
                trie.insert(word);
            }
    
            int m = board.length;
            int n = board[0].length;
            boolean[][] visited = new boolean[m][n];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    dfs(board, visited, "", i, j, trie);
                }
            }
    
            return new ArrayList<String>(res);
        }
    
        public void dfs(char[][] board, boolean[][] visited, String str, int x, int y, Trie trie) {
            if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) return;
            if (visited[x][y]) return;
    
            str += board[x][y];
            if (!trie.startsWith(str)) return;
    
            if (trie.search(str)) {
                res.add(str);
            }
    
            visited[x][y] = true;
            dfs(board, visited, str, x - 1, y, trie);
            dfs(board, visited, str, x + 1, y, trie);
            dfs(board, visited, str, x, y - 1, trie);
            dfs(board, visited, str, x, y + 1, trie);
            visited[x][y] = false;
        }
    }
    View Code

    学习之处:

    • 思路很简单,就是回溯,但是有一点需要自己学习,由于会有重复的结果,所以在我的代码里面需要加入 if(!list.contains(word))的判断以确定是否添加到结果List里面,但是在别人代码里面是用的Set<String> res = new HashSet<String>(); 这样直接过滤掉了重复的结果,如此一来节约了不少时间,最后再用return new ArrayList<String>(res);将set转换成List,完工!
  • 相关阅读:
    Java泛型的协变
    【LeetCode】LeetCode——第14题:Longest Common Prefix
    【BZOJ4008】【HNOI2015】亚瑟王 概率DP
    git merge 和 git merge --no-ff
    自己定义View时,用到Paint Canvas的一些温故,讲讲平时一些效果是怎么画的(基础篇 一)
    Spring Boot 集成MyBatis
    .net framework中重新注册IIS
    FireFox插件SQLite Manager的使用
    sqlite developer注册码
    javascript 中用到的时间戳函数
  • 原文地址:https://www.cnblogs.com/sunshisonghit/p/4542192.html
Copyright © 2011-2022 走看看