常见情景:
括号算法:
Leecode 301.删除无效的括号
以下是leecode官方解法,思路基础有二:
- 括号有效检测(leecode 官方题解):
当遍历到「左括号」的时候:「左括号」数量加 11。
当遍历到「右括号」的时候:如果此时「左括号」的数量不为 0,则「右括号」可以与之前遍历到的「左括号」匹配,此时「左括号」出现的次数 -1;如果此时「左括号」的数量为 00,「右括号」数量加 11。 - 括号生成(匹配算法)
vector<string> res;
vector<string> removeInvalidParentheses(string s) {
int lr = 0, rr = 0;//定义需要删除的左右括号的个数(括号匹配)
for(auto chr : s){
if(chr == '(')lr++;
else if(chr == ')'){
if(!lr)rr++;
else lr--;
}
}
backtracking(s, lr, rr, 0);
return res;
}
void backtracking(string cur, int lr, int rr, int start){
if(!lr && !rr){
if(JudgeValid(cur))res.push_back(cur);//如果没有需要删除的且当前括号合法
return;
}
for(int i = start; i < cur.size(); i++){
if( i != start && cur[i] == cur[i - 1])continue;//如果该括号和下一个相同,不需要处理
if(lr + rr > cur.size() - i)return;
if(lr > 0 && cur[i] =='(')backtracking(cur.substr(0, i) + cur.substr(i + 1), lr - 1, rr, i);//删除一个左括号
if(rr > 0 && cur[i] ==')')backtracking(cur.substr(0, i) + cur.substr(i + 1), lr, rr - 1, i);//删除一个右括号
}
}
bool JudgeValid(string s){//判断括号是否匹配(合法)
int cnt = 0;
for(auto chr : s){
if(chr == '(')cnt++;
else if(chr == ')'){
cnt--;
if(cnt < 0)return false;
}
}
return !cnt;
}
括号生成算法
void dfs(const int n, int left, int right, string cur, vector<string> &ans){
if(left == n && right == n) {
ans.push_back(cur);
return;
}
if(left < right)return;//不合规,剪枝
if(left < n)dfs(n, left + 1, right, cur + '(', ans);//左边少,加一个左括号
if(right < n)dfs(n, left, right + 1, cur + ')', ans);//右边少,加一个右括号
}
vector<string> generateParenthesis(int n) {
vector<string>ans;
string cur = "";
if(!n)return ans;
dfs(n, 0, 0, cur, ans);
return ans;
}
Leecode 79. 单词搜索
深搜常用回溯,广搜常用队列。
class Solution {
public:
bool backtracking(const vector<vector<char>>& board,vector<vector<bool>>& visit,const string& word,int pos,int x,int y)
{
if(visit[x][y] || board[x][y] != word[pos]) return false;
if(pos == word.size()-1) return true;
visit[x][y] = true;
int xsize = board.size(),ysize = board[0].size();
visit[x][y] = true;
if(x && board[x-1][y] == word[pos+1])
if(backtracking(board,visit,word,pos+1,x-1,y)) return true;
if(y && board[x][y-1] == word[pos+1])
if(backtracking(board,visit,word,pos+1,x,y-1)) return true;
if(x+1<=xsize-1)
if(backtracking(board,visit,word,pos+1,x+1,y)) return true;
if(y+1<=ysize-1)
if(backtracking(board,visit,word,pos+1,x,y+1)) return true;
//以上均不可以直接return backtracking, 判断结果会有问题
visit[x][y] = false;
return false;
}
bool exist(vector<vector<char>>& board, string word) {
vector<vector<bool>>visit(board.size(), vector<bool>(board[0].size(), false));
for(int i = 0; i < board.size(); i++)
for(int j = 0; j < board[0].size(); j++){
if(board[i][j] == word[0] && backtracking(board,visit,word,0,i,j)) return true;
//这里也不可以直接return 在循环中可能会找错,找到其他无法构成word但是首字符相同的问题。
}
return false;
}
};