Word Search 题解

来源:互联网 发布:sony平板 软件 编辑:程序博客网 时间:2024/04/29 02:24

题目:

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, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =
[
[‘A’,’B’,’C’,’E’],
[‘S’,’F’,’C’,’S’],
[‘A’,’D’,’E’,’E’]
]

word = “ABCCED”, -> returns true,
word = “SEE”, -> returns true,
word = “ABCB”, -> returns false.

Difficulty: Medium

翻译:

给定一个矩阵和一个字符串,矩阵中的字母可以横着连竖着连不能斜着连,问这个字符串是否存在于矩阵中

分析:

题意简单明了,所以不必过多分析,很自然就会想到用深度遍历的思想,那么思路也就是现成的了
但是,由于字符串中的字母是有重复的,所以需要解决一个问题,如何标记访问过的节点,防止回溯时多次遍历同一个节点?单独开辟一个空间存放访问过的坐标是个可行的办法,但是在递归中继续开辟新空间会在每次递归中让空间复杂度成倍增长,实际上利用好递归的性质,只要利用原矩阵中的点就行了

代码:

class Solution {public:    bool exist(vector<vector<char>>& board, string word) {        if (board.size() == 0 || board[0].size() == 0)            return true;        for (int i = 0; i<board.size(); i++) {            for (int j = 0; j<board[0].size(); j++) {                if (board[i][j] == word[0])                    if (check(board, word, i, j))                        return true;            }        }        return false;    }    bool check(vector<vector<char>>& board, string word, int i, int j) {        if (word.length() == 0)            return true;        if (i<0 || j<0 || i >= board.size() || j >= board[0].size())            return false;        if (word[0] == board[i][j]) {            char c = word[0];            board[i][j] = '\0';            if (check(board, word.substr(1), i + 1, j) ||                check(board, word.substr(1), i - 1, j) ||                check(board, word.substr(1), i, j + 1) ||                check(board, word.substr(1), i, j - 1))                return true;            board[i][j] = c;        }        return false;    }};

注意这段:

if (word[0] == board[i][j]) {            char c = word[0];            board[i][j] = '\0';            if (check(board, word.substr(1), i + 1, j) ||                check(board, word.substr(1), i - 1, j) ||                check(board, word.substr(1), i, j + 1) ||                check(board, word.substr(1), i, j - 1))                return true;            board[i][j] = c;        }

中间的if是递归回溯不谈,我们新建一个字符存放矩阵中访问过的元素,然后消除矩阵中这个元素,等到回溯回来,不需要访问时再还原,可能有同学有疑问,怎么保证恢复的准确性?实际上,每次递归的元素位置和值都会保存下来,等到返回到这层递归时所有的“现场”会跟进入下层递归前一模一样,就像组成原理里的嵌套中断一样,这样,在一次递归中改变又恢复的元素位置肯定是一样的
实际上递归就是计算机帮我们保存断点,如果我们不用递归而用栈的话是一样的,只是这个栈编译器帮我们弄好了

0 0
原创粉丝点击