LeetCode 刷题【77. 组合、78. 子集、79. 单词搜索】
77. 组合
自己做
解:回溯法
class Solution {
public:void getCombine(int begin, int end, int k, vector<int> &combine, vector<vector<int>> &res){if(combine.size() == k){ //取到组合res.push_back(combine);return;}for(int i = begin; i <= end; i++){ //逐个选取当前点combine.push_back(i); //选点getCombine(i + 1, end + 1, k, combine, res);combine.pop_back(); //还原}}vector<vector<int>> combine(int n, int k) {int begin = 1; //第一个数选取起点int end = n - k + 1; //第一个数选取终点vector<vector<int>> res;vector<int> combine;getCombine(begin, end, k, combine, res);return res;}
};
78. 子集
自己做
解:回溯法
class Solution {
public:void getCombine(int begin, int end, vector<int>& nums, vector<int> &combine, vector<vector<int>> &res){if(begin > end) //越界return;for(int i = begin; i <= end; i++){ //逐个选取当前点combine.push_back(nums[i]); //选点res.push_back(combine); //加入结果getCombine(i + 1, end, nums, combine, res);combine.pop_back(); //还原}}vector<vector<int>> subsets(vector<int>& nums) {vector<vector<int>> res;vector<int> combine;res.push_back(vector<int>()); //插入空集getCombine(0, (int)nums.size() - 1, nums, combine, res);return res;}
};
79. 单词搜索
自己做
解:回溯法
class Solution {
public:bool is_exist = false;void search(int i, int j, int k, string &word, vector<vector<char>>& board, vector<vector<bool>>& acquire){ if(k == word.size()){ //取到了is_exist = true;return;}//还没取到的情况下(!is_exis), 试着取左边(能取到左边=》 j > 0, 左边没有被取过=》 !acquire[i][j - 1], 左边符合下一个字符=》 board[i][j - 1] == word[k])if(!is_exist && j > 0 && !acquire[i][j - 1] && board[i][j - 1] == word[k]){acquire[i][j - 1] = true; //标记取过(i, j - 1)search(i, j - 1, k + 1, word, board, acquire);acquire[i][j - 1] = false; //还原}//还没取到的情况下(!is_exis), 试着取上边(能取到上边=》 i > 0, 上边没有被取过=》 !acquire[i - 1][j], 上边符合下一个字符=》 board[i - 1][j] == word[k])if(!is_exist && i > 0 && !acquire[i - 1][j] && board[i - 1][j] == word[k]){acquire[i - 1][j] = true; //标记取过(i - 1, j)search(i - 1, j, k + 1, word, board, acquire);acquire[i - 1][j] = false; //还原}//还没取到的情况下(!is_exis), 试着取右边(能取到右边=》 j < board[0].size() - 1, 右边没有被取过=》 !acquire[i][j + 1], 右边符合下一个字符=》 board[i][j + 1] == word[k])if(!is_exist && j < (int)board[0].size() - 1 && !acquire[i][j + 1] && board[i][j + 1] == word[k]){acquire[i][j + 1] = true; //标记取过(i, j + 1)search(i, j + 1, k + 1, word, board, acquire);acquire[i][j + 1] = false; //还原}//还没取到的情况下(!is_exis), 试着取下边(能取到下边=》 i < board.size() - 1, 下边没有被取过=》 !acquire[i + 1][j], 下边符合下一个字符=》 board[i + 1][j] == word[k])if(!is_exist && i < (int)board.size() - 1 && !acquire[i + 1][j] && board[i + 1][j] == word[k]){acquire[i + 1][j] = true; //标记取过(i + 1, j)search(i + 1, j, k + 1, word, board, acquire);acquire[i + 1][j] = false; //还原}}bool exist(vector<vector<char>>& board, string word) {int m = board.size();int n = board[0].size();vector<vector<bool>> acquire(m, vector<bool>(n, false));for(int i = 0; i < m; i++) //取第一个字符for(int j = 0; j < n; j++){if(board[i][j] == word[0]){acquire[i][j] = true; //标记取过(i, j)search(i, j, 1, word, board, acquire);acquire[i][j] = false; //还原if(is_exist) //找到了return is_exist;}}return is_exist; //找遍了都没有找到}
};
看题解
剪枝
https://leetcode.cn/problems/word-search/solutions/2927294/liang-ge-you-hua-rang-dai-ma-ji-bai-jie-g3mmm
代码如下
class Solution {static constexpr int DIRS[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public:bool exist(vector<vector<char>>& board, string word) {unordered_map<char, int> cnt;for (auto& row : board) {for (char c : row) {cnt[c]++;}}// 优化一unordered_map<char, int> word_cnt;for (char c : word) {if (++word_cnt[c] > cnt[c]) {return false;}}// 优化二if (cnt[word.back()] < cnt[word[0]]) {ranges::reverse(word);}int m = board.size(), n = board[0].size();auto dfs = [&](this auto&& dfs, int i, int j, int k) -> bool {if (board[i][j] != word[k]) { // 匹配失败return false;}if (k + 1 == word.length()) { // 匹配成功!return true;}board[i][j] = 0; // 标记访问过for (auto& [dx, dy] : DIRS) {int x = i + dx, y = j + dy; // 相邻格子if (0 <= x && x < m && 0 <= y && y < n && dfs(x, y, k + 1)) {return true; // 搜到了!}}board[i][j] = word[k]; // 恢复现场return false; // 没搜到};for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (dfs(i, j, 0)) {return true; // 搜到了!}}}return false; // 没搜到}
};