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

    问题:

    给定一个字母表,求给定的单词组中,能够在字母表中找到的单词。(相邻两个字母,上下左右连续)

    Example 1:
    Input: board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
    Output: ["eat","oath"]
    
    Example 2:
    Input: board = [["a","b"],["c","d"]], words = ["abcb"]
    Output: []
     
    Constraints:
    m == board.length
    n == board[i].length
    1 <= m, n <= 12
    board[i][j] is a lowercase English letter.
    1 <= words.length <= 3 * 104
    1 <= words[i].length <= 10
    words[i] consists of lowercase English letters.
    All the strings of words are unique.
    

            

      

    解法:Backtracking(回溯算法)

    • path:该单词,目前为止匹配到的字母处。
    • optlists:从字母表当前位置,上下左右下一个位置选择的字母。

    ⚠️  注意:由于本问题上下左右皆可移动,有可能出现走过的cell,又被走到,因此需要将做过的cell标记为“#”

    • 初始化操作:
      • 拿着每一个待check的单词,在字母表中进行尝试。
      • 对于每个单词,都要从字母表的每个cell开始进行尝试。
    • 结束条件:
      • 找到这个单词(找到最后一个字母),将该单词加入res。
      • 上下左右都没有下一个字母,没找到这个单词,返回即可。

    ♻️  优化:为偏移遍历待选择的各单词,建立数据结构WordPath。

    每个单词的各个字符迁移,通过链表next指针链接,到达最后一个字符,将该单词(整个path)保存在string word中。

    代码参考:

     1 class WordPath {
     2 public:
     3     string word;
     4     vector<WordPath*> next;
     5     WordPath() {
     6         next = vector<WordPath*>(26, NULL);
     7     }
     8 };
     9 class Solution {
    10 public:
    11     WordPath createWP(vector<string>& words) {
    12         WordPath root;
    13         WordPath* p;
    14         for(string word:words) {
    15             p = &root;
    16             for(char w:word) {
    17                 if(!p->next[w-'a']) p->next[w-'a'] = new WordPath();
    18                 p = p->next[w-'a'];
    19             }
    20             p->word = word;
    21         }
    22         return root;
    23     }
    24     void DFS(vector<string>& res, vector<vector<char>>& board, int i, int j, WordPath* p) {
    25         char c = board[i][j];
    26         if(c=='#' || !p->next[c-'a']) return;//'#':visited
    27         p=p->next[c-'a'];
    28         if(p->word.length()>0) {
    29             res.push_back(p->word);
    30             p->word.clear();
    31         }
    32         board[i][j] = '#';
    33         if(i < board.size()-1) DFS(res, board, i+1, j, p);
    34         if(j < board[0].size()-1) DFS(res, board, i, j+1, p);
    35         if(i > 0) DFS(res, board, i-1, j, p);
    36         if(j > 0) DFS(res, board, i, j-1, p);
    37         board[i][j] = c;
    38         return;
    39     }
    40     vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
    41         WordPath root = createWP(words);
    42         vector<string> res;
    43         for(int i=0; i<board.size(); i++) {
    44             for(int j=0; j<board[0].size(); j++) {
    45                 DFS(res, board, i, j, &root);
    46             }
    47         }
    48         return res;
    49     }
    50 };
  • 相关阅读:
    mybatis设置添加新对象数据的时候id使用uuid类型自动写入数据库
    mysql大小写敏感配置
    linux中iproute2工具介绍
    openwrt中补丁命名规则
    Java: ThreadLocal 用法详解和原理(转)
    Git: tag 标签操作
    android: 详解 Android 中的 HandlerThread(转)
    android: drawable中同时设置state_enabled和和state_pressed不起作用的问题
    C语言:记录32bit数据的一些常用位操作
    android: 分享一个带多行选择功能的RadioGroup
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14262260.html
Copyright © 2011-2022 走看看