`

Leetcode - Word Search II

 
阅读更多
iven 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"].

[分析] 直接的思路是调用Word Search的方法判断输入数组中的各个单词是否在board中,这种方法是低效的。网上ljiabin 同学的博客给出了一个较好的思路,使用输入单词数组构造一个Trie字典,穷搜一遍board判断哪些字符组合出现在字典中则加入到结果集中。该方法两个好处,一是仅需穷搜一遍,二是穷搜过程中可以剪枝计算,一旦当前形成的单词甚至不是Trie树的前缀则无需判断其后续递归。为避免重复,先使用Set获取结果集最后转为List。
自己实现时使用StringBuilder表示当前已形成的单词再各层递归中传递,在{{'a','b'},{'c', 'd'}},"acdb"这个case fail了好久,最后debug出来是因为每次递归后没有恢复到初始状态。递归可以更新结果,但每层递归结束切记要恢复相关状态变量为开始本次递归时的状态,想到了那首经典的诗,“我挥一挥衣袖,不带走一片云彩” O(∩_∩)O~


[ref]
ljiabin 同学的博客
http://blog.csdn.net/ljiabin/article/details/45846527

public class Solution {
    public List<String> findWords(char[][] board, String[] words) {
        if (board == null || board.length == 0 || board[0].length == 0 
            || words == null || words.length == 0)
            return new ArrayList<String>();
        Trie dict = new Trie();
        for (int i = 0; i < words.length; i++)
            dict.insert(words[i]);
        int rows = board.length;
        int cols = board[0].length;
        Set<String> resultSet = new HashSet<String>();
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                dfs(board, i, j , new StringBuilder(), new boolean[rows][cols], dict, resultSet);
            }
        }
        return new ArrayList<String>(resultSet);
    }
    public void dfs(char[][] board, int i, int j, StringBuilder curr, boolean[][] used, Trie dict, Set<String> result) {
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || used[i][j])
            return;
        curr.append(board[i][j]);
        String currstr = curr.toString();
        if (!dict.isPrefix(currstr)) {
            curr.deleteCharAt(curr.length() - 1); //容易被忽略,恢复递归初始状态
            return;    
        }
        if (dict.search(currstr))
            result.add(currstr);
        used[i][j] = true;
        dfs(board, i, j + 1, curr, used, dict, result);
        dfs(board, i, j - 1, curr, used, dict, result);
        dfs(board, i + 1, j, curr, used, dict, result);
        dfs(board, i - 1, j, curr, used, dict, result);
        // 恢复递归初始状态
        used[i][j] = false;
        curr.deleteCharAt(curr.length() - 1);
    }
}

class TrieNode {
    TrieNode[] children;
    public static final int ALPHABET_NUM = 26;
    boolean isAWord;
    public TrieNode() {
        children = new TrieNode[ALPHABET_NUM];
    }
}

class Trie {
    public TrieNode root;
    public Trie() {
        root = new TrieNode();
    }
    public void insert(String word) {
        TrieNode p = root;
        for (int i = 0; i < word.length(); i++) {
            int idx = word.charAt(i) - 'a';
            if (p.children[idx] == null) {
                p.children[idx] = new TrieNode();
            }
            p = p.children[idx];
        }
        p.isAWord = true;
    }
    public boolean search(String word) {
        TrieNode p = root;
        for (int i = 0; i < word.length(); i++) {
            int idx = word.charAt(i) - 'a';
            if (p.children[idx] == null)
                return false;
            p = p.children[idx];
        }
        return p.isAWord;
    }
    public boolean isPrefix(String word) {
        TrieNode p = root;
        for (int i = 0; i < word.length(); i++) {
            int idx = word.charAt(i) - 'a';
            if (p.children[idx] == null)
                return false;
            p = p.children[idx];
        }
        return true;
    }
}
分享到:
评论

相关推荐

    _leetcode-python.pdf

    - Word Search: 给定一个m×n的二维字符网格board和一个单词(字符串)word,如果word存在于网格中,则返回true;否则,返回false。 - Minimum Window Substring: 给定两个字符串s和t,找出s中包含t所有字母的最小子...

    C语言-leetcode题解之79-word-search.c

    关于“C语言-leetcode题解之79-word-search.c”,这是一份针对leetcode在线编程题库中编号为79的题目“Word Search”的C语言解决方案。这道题属于回溯算法的经典应用,题目要求在一个二维的字符网格中寻找是否存在一...

    python-leetcode题解之079-Word-Search

    python python_leetcode题解之079_Word_Search

    js-leetcode题解之79-word-search.js

    此外,"js-leetcode题解之79-word-search.js" 这个文件的标题和描述还提示我们,该文件可能是一段 JavaScript 语言编写的代码,用于解决 LeetCode 上编号为 79 的题目。文件的具体内容可能会包含题目描述、解题思路...

    c语言-leetcode题解之0079-word-search.zip

    LeetCode题号0079的题目是Word Search,即单词搜索。这个问题属于经典的回溯算法应用场景,具体要求是在一个二维的字符数组中查找是否存在某个给定的单词。这个问题不仅考验了编程者对回溯算法的理解和应用,还涉及...

    AlgorithmAndLeetCode#itcharge-LeetCode-Py#0211. 添加与搜索单词 - 数据结构设计

    void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配bool search(word) 如果数据结构中存在字符串与 wor

    leetcode耗时-word-search-ii:查词二

    leetcode 耗时查词二 给定一个 2D 板和字典中的单词列表,找到板中的所有单词。 每个单词必须由顺序相邻单元格的字母构成,其中“相邻”单元格是水平或垂直相邻的单元格。 同一个字母单元格不能在一个单词中多次使用...

    js-leetcode题解之127-word-ladder.js

    本文探讨的是leetcode中127号问题——Word Ladder(单词梯度)的JavaScript解法。 Word Ladder问题是一个经典的字符串转换问题,要求给定一个起始单词beginWord,一个结束单词endWord和一个单词列表wordList,我们...

    扩展矩阵leetcode-Leetcode:LeetcodeAnswer-Java

    扩展矩阵leetcode ...63.不同路径II uniquePathsWithObstacles 139.单词拆分 wordBreak 279.完全平方数 numSquares 排序 56.合并区间 merge 75.颜色分类 sortColors 179.最大数 largestNumber 324.摆

    js-leetcode题解之139-word-break.js

    LeetCode题号139的这道“Word Break”题便是这样一个问题。该问题要求实现一个函数,该函数接收两个参数:一个字符串s和一个字符串数组wordDict作为字典,返回一个布尔值,表示是否可以将字符串s拆分为字典中的单词...

    hihocoder和leetcode-leetcode:leetcode

    hihocoder和leetcode leetcode 目录名 功能 Array 数组 Backtracking 回溯 Bit_Manipulation 位操作 Design 数据结构设计 ...单词搜索:word_search.cpp hihocoder String 文章重排:give_my_text_back.cpp

    LeetCode最全代码

    * [Binary Search Tree](https://github.com/kamyu104/LeetCode#binary-search-tree) * [Breadth-First Search](https://github.com/kamyu104/LeetCode#breadth-first-search) * [Depth-First Search]...

    leetcode添加元素使和等于-Leetcode-Problems-Java-Python--with-Markdown-Explanati

    leetcode添加元素使和等于 October 2nd Reviews 79 word Search 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, ...

    LeetCode:关于LeetCode.com和ACM的一些算法问题

    LeetCode一些 LeetCode 题目的进阶解法,追求极致效率。由于 LeetCode 已启用中文版域名 leetcode-... Word-Search-II题目: | 英文站源码:./problem-0212-Word-Search-II/标签:哈希表,双向链表难度:困难 / Hard

    javalruleetcode-leetcode-python:leetcode问题的Python解决方案

    leetcode 刷题笔记 记录一些刷题细节,很惭愧只做了一点微小的工作 4.13 162题. Find Peak Element.Binary search,需要比较nums[mid]和nums[mid+1]. 4.12 212题. Word Search II. 用trie tree存word list,然后dfs. ...

    leetcode不会-word-search:二维网格中的单词搜索

    leetcode 不会词搜索 给定一个 2D 板和一个单词,查找该单词是否存在于网格中。 单词可以由顺序相邻的单元格的字母构成,其中“相邻”单元格是水平或垂直相邻的单元格。 同一个字母单元格不能多次使用。 Example: ...

    圆和矩形是否重叠leetcode-leetcode_solutions:leetcode_solutions

    圆和椭圆重叠leetcode ——#158 尖端 关心特殊情况 从不同的方向思考 简单的 大批 1.Two Sum -&gt; 使用哈希表避免遍历列表448.查找数组中消失的所有数字-&gt; 1.建立缓冲区来计算数字| 2.使用数组作为带符号的缓冲区118....

    LeetCode-Feb2021

    例如,"Word Search"(单词搜索)问题,可以通过DFS遍历二维数组寻找单词路径。 四、动态规划 动态规划是解决复杂问题的利器,如"Longest Increasing Subsequence"(最长递增子序列)问题。Java中动态规划的实现...

    leetcode1-200题源码(c++)

    4. 题目79:单词搜索 (Word Search) 在一个二维字符网格中查找给定的单词,使用深度优先搜索(DFS)或广度优先搜索(BFS)策略,结合回溯技术来实现。 5. 题目4:寻找两个有序数组的中位数 (Median of Two Sorted ...

Global site tag (gtag.js) - Google Analytics