zoukankan      html  css  js  c++  java
  • 79.Word Search

    给定一个字符矩阵,以及一个字符串,求字符矩阵能否组成字符串,字符组建规则:当前字符上下左右都可以组建成字符串,一个位置的字符只能组建一次。

    board =
    [
    ['A','B','C','E'],
    ['S','F','C','S'],
    ['A','D','E','E']
    ]
    Given word = "ABCCED", return true.
    Given word = "SEE", return true.
    Given word = "ABCB", return false.


    思路:
    使用DFS来查找答案,每一次递归调用,分别遍历当前字符上下左右4个位置的字符,而对于怎么判断组建的字符串到多少位了,用 n 来记录即可,n表示遍历到给定字符串 word的多少位了,当 n == word.size( ) ,说明已经将字符串word遍历完了,因为当矩阵字符与字符串对 应下标字符不相等时,就跳出当前递归,返回false了,而 n == word.size( ),表示前面的字符都与字符串word相等,即表示找到答案了,返回true。防止将一个字符多次使用,即防止走回头路,需要将已经遍历的字符修改成 '0',当4个位置都遍历完时,再将原来的值恢复,既得到了答案,又没有修改矩阵,还不引入额外的空间,一举三得。

    class Solution {
    public:
        bool exist(vector<vector<char>>& board, string word) {
            if (board.empty() || board[0].empty()) return false;
            int row = board.size(), col = board[0].size();
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if (board[i][j] != word[0]) continue;//当首字母相等时才递归判断,否则跳过。减少不必要的递归调用开销
                    if (existDFS(board, word, 0, i, j)) return true;
                }
            }
            return false;
        }
        bool existDFS(vector<vector<char>>& board, string& word, int n, int i, int j) {
            if (n == word.size()) return true;
            if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[n]) return false;
            char c = board[i][j];
            board[i][j] = '0';
            bool res = (existDFS(board, word, n + 1, i, j - 1) || existDFS(board, word, n + 1, i, j + 1)
                || existDFS(board, word, n + 1, i - 1, j) || existDFS(board, word, n + 1, i + 1, j));
            board[i][j] = c;
            return res;
        }
    };

    注意的点:
    不要将4个位置都遍历完了,最后再一起判断,如下:
      bool res1 = existDFS(board, word, n + 1, i, j - 1);
      bool res2 = existDFS(board, word, n + 1, i, j + 1);
      bool res3 = existDFS(board, word, n + 1, i - 1, j);
      bool res4 = existDFS(board, word, n + 1, i + 1, j);
      board[i][j] = c;
      return (res1 || res2 || res3 || res4);


    因为这样必须将4个位置都遍历完,当矩阵特别大,字符串特别大时,就算 res1 找到了答案,也还需要耗费大量时间去遍历 res2, res3, res4. 最终导致超时,OJ不AC
    使用“或”运算,只要找到一个答案为真,则不再继续找另外的位置了。

  • 相关阅读:
    前端学习(十五):了解 Javascript
    前端学习(十四):CSS布局
    前端学习(十三):CSS盒子模型
    python pip及安装包安装
    linux搜索日志的命令方法
    spring boot GET请求方式无法访问的原因
    [线上问题]redisTemplate.setValueSerializer 对redis值的全局设置影响
    des对称加密算法 Invalid key length: 8 bytes
    jdk导入证书命令 https升级证书对支付的影响
    事务管理 异常机制
  • 原文地址:https://www.cnblogs.com/luo-c/p/13028556.html
Copyright © 2011-2022 走看看