leetcode Word Search
给定一个board字符矩阵,可以从任意一个点开始经过上下左右的方式走,每个点只能走一次,如果存在一条路走过的字符等于给定的字符串,那么返回true
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 =
[ ["ABCE"], ["SFCS"], ["ADEE"] ]
word = "ABCCED"
, -> returns true
,
word = "SEE"
, -> returns true
,
word = "ABCB"
, -> returns false
.
这题花了我一个多小时找一个小bug。。。
这题也是用回溯法。分上下左右四个方向回溯。
如下:
class Solution { public: bool dfs79(vector<vector<char> > &board, vector<vector<bool> > &bit, string word, string &foundS, int x, int y) { if (x >= 0 && y >= 0 && x < board.size() && y < board[0].size() && bit[x][y] == false && board[x][y] == word[foundS.size()]) { foundS += board[x][y]; bit[x][y] = true; } else return false; if (foundS.size() == word.size()) return true; if (dfs79(board, bit, word, foundS, x, y-1)) return true; if (dfs79(board, bit, word, foundS, x-1, y)) return true; if (dfs79(board, bit, word, foundS, x, y+1)) return true; if (dfs79(board, bit, word, foundS, x+1, y)) return true; bit[x][y] = false; foundS = foundS.substr(0, foundS.size() - 1); return false; } bool exist(vector<vector<char> > &board, string word) { int row = board.size(); if (row == 0) return false; int col = board[0].size(); for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) { if (board[i][j] == word[0]) { string foundS = ""; vector<vector<bool> > bit(row, vector<bool>(col)); // 初始化都为false if (dfs79(board, bit, word, foundS, i, j)) return true; } } return false; } };
但是如上的代码,会超时。我看了诸多网上解题,我的思路没有问题啊。我纠结啊,改啊。把我的foundS改为不用字符串,改为用index下标存,因为字符串操作会费时一些。则如下:
class Solution { public: bool dfs79(vector<vector<char> > &board, vector<vector<bool> > &bit, string word, int index, int x, int y) { if (x >= 0 && y >= 0 && x < board.size() && y < board[0].size() && bit[x][y] == false && board[x][y] == word[index]) { bit[x][y] = true; } else return false; if (index == word.size()-1) return true; if (dfs79(board, bit, word, index + 1, x, y-1)) return true; if (dfs79(board, bit, word, index + 1, x-1, y)) return true; if (dfs79(board, bit, word, index + 1, x, y+1)) return true; if (dfs79(board, bit, word, index + 1, x+1, y)) return true; bit[x][y] = false; return false; } bool exist(vector<vector<char> > &board, string word) { int row = board.size(); if (row == 0) return false; int col = board[0].size(); for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) { if (board[i][j] == word[0]) { vector<vector<bool> > bit(row, vector<bool>(col)); // 初始化都为false if (dfs79(board, bit, word, 0, i, j)) return true; } } return false; } };
还是超时,然后我又是纠结啊。我想到网上的解法是不用bit存走过的路径的,所以我又各种改,把bit去掉,变成‘#’。如下:Accept了
说明是bit的问题?
class Solution { public: bool dfs79(vector<vector<char> > &board, string word, int index, int x, int y) { if (x >= 0 && y >= 0 && x < board.size() && y < board[0].size() && board[x][y] == word[index]); else return false; if (index == word.size()-1) return true; char tmp = board[x][y]; board[x][y] = '#'; if (dfs79(board, word, index + 1, x, y-1)) return true; if (dfs79(board, word, index + 1, x-1, y)) return true; if (dfs79(board, word, index + 1, x, y+1)) return true; if (dfs79(board, word, index + 1, x+1, y)) return true; board[x][y] = tmp; return false; } bool exist(vector<vector<char> > &board, string word) { int row = board.size(); if (row == 0) return false; int col = board[0].size(); for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) { if (board[i][j] == word[0]) { if (dfs79(board, word, 0, i, j)) return true; } } return false; } };
既然是bit的问题,我还是不死心,为什么我之前的就不行呢,于是我想知道是不是bit的初始化的问题费时,然后改成如下:只初始化一次
class Solution { public: bool dfs79(vector<vector<char> > &board, vector<vector<bool> > &bit, string word, int index, int x, int y) { if (x >= 0 && y >= 0 && x < board.size() && y < board[0].size() && bit[x][y] == false && board[x][y] == word[index]) { bit[x][y] = true; } else return false; if (index == word.size()-1) return true; if (dfs79(board, bit, word, index + 1, x, y-1)) return true; if (dfs79(board, bit, word, index + 1, x-1, y)) return true; if (dfs79(board, bit, word, index + 1, x, y+1)) return true; if (dfs79(board, bit, word, index + 1, x+1, y)) return true; bit[x][y] = false; return false; } bool exist(vector<vector<char> > &board, string word) { int row = board.size(); if (row == 0) return false; int col = board[0].size(); vector<vector<bool> > bit(row, vector<bool>(col)); // 初始化都为false vector<vector<bool> > em(row, vector<bool>(col)); // 初始化都为false for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) { if (board[i][j] == word[0]) { bit = em; if (dfs79(board, bit, word, 0, i, j)) return true; } } return false; } };
终于通过,果然是在初始化话了很多时间(这个绝对是坑爹啊,花了一个小时找到这个bug)。
于是我又想,那还是用foundS呢,试了下,又超时,所以知道了费时的两个地方,一个是字符串处理,一个是bit初始化。