牛客101:递归/回溯
目录
一、没有重复项数字的全排列
二、有重复项数字的全排列
三、岛屿数量
四、字符串的排列
五、N皇后
六、括号生成
七、矩阵最长递增路径
这个专栏写得很顺畅
一、没有重复项数字的全排列
没有重复项数字的全排列_牛客题霸_牛客网

无重复->暴力枚举,check剪枝
牛客这边好像类内成员属性不给初始化的,所以将其设置为全局变量。
#include <vector>
bool check[7];
vector<int> path;
vector<vector<int>> ret;
int _n;
class Solution {
public:vector<vector<int> > permute(vector<int>& num) {_n=num.size();//题目要求sort(num.begin(),num.end());dfs(num);return ret;}void dfs(vector<int>&num){if(path.size()==_n){ret.push_back(path);return;}for(int i=0;i<_n;++i){if(!check[i]){check[i]=true;path.push_back(num[i]);dfs(num);check[i]=false;path.pop_back();}}}
};
二、有重复项数字的全排列
有重复项数字的全排列_牛客题霸_牛客网

有重复?排序+check分层判断
bool check[9];
int _n;
vector<int> path;
vector<vector<int>> ret;
class Solution {
public:vector<vector<int> > permuteUnique(vector<int>& num) {_n=num.size();sort(num.begin(),num.end());dfs(num);return ret;}void dfs(vector<int>&num){if(path.size()==_n){ret.push_back(path);return;}for(int i=0;i<_n;++i){if(!check[i]){if(i==0||num[i]!=num[i-1]||check[i-1]){check[i]=true;path.push_back(num[i]);dfs(num);path.pop_back();check[i]=false;}}}}
};
三、岛屿数量
岛屿数量_牛客题霸_牛客网


check标记
class Solution {int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1},m,n;bool check[301][301];
public:int solve(vector<vector<char>>& grid) {m=grid.size(),n=grid[0].size();int ret=0;for(int i=0;i<m;++i){for(int j=0;j<n;++j){if(grid[i][j]=='1'&&!check[i][j]){++ret;//check!dfs(grid,i,j);}}}return ret;}void dfs(vector<vector<char>>& grid,int i,int j){check[i][j]=true;for(int k=0;k<4;++k){int x=i+dx[k],y=j+dy[k];if(x>=0&&x<m&&y>=0&&y<n&&grid[x][y]=='1'&&!check[x][y]){dfs(grid,x,y);}}}
};
四、字符串的排列
字符串的排列_牛客题霸_牛客网


其实就是有重复元素全排列
int _n;
string path;
vector<string> ret;
bool check[11];
class Solution {
public:vector<string> Permutation(string str) {_n=str.size();sort(str.begin(),str.end());dfs(str);return ret;}void dfs(string str){if(path.size()==_n){ret.push_back(path);return;}for(int i=0;i<_n;++i){if(!check[i]){if(i==0||str[i]!=str[i-1]||check[i-1]){check[i]=true;path.push_back(str[i]);dfs(str);path.pop_back();check[i]=false;}}}}
};
五、N皇后
N皇后问题_牛客题霸_牛客网


题意要求特判
递归该层处理该行
int _n;
bool Col[10],Dig1[20],Dig2[20];
int ret;
class Solution {
public:int Nqueen(int n) {_n=n;dfs(0);return ret;}void dfs(int row){if(row==_n){++ret;return;}for(int col=0;col<_n;++col){if(!Col[col]&&!Dig1[row-col+_n]&&!Dig2[row+col]){Col[col]=Dig1[row-col+_n]=Dig2[row+col]=true;dfs(row+1);Col[col]=Dig1[row-col+_n]=Dig2[row+col]=false;}}}
};
六、括号生成
括号生成_牛客题霸_牛客网

依旧是根据题目要求,写特殊判断
int _n;
string path;
vector<string> ret;
class Solution {
public:vector<string> generateParenthesis(int n) {_n=n;dfs(0,0);return ret;}//dfs每层保证右括号数量<=左括号数量,并且二者数量都不能超过nvoid dfs(int LeftNum,int RightNum){if(RightNum==_n){ret.push_back(path);return;}if(LeftNum<_n){path.push_back('(');dfs(LeftNum+1,RightNum);path.pop_back();}if(RightNum<LeftNum){path.push_back(')');dfs(LeftNum,RightNum+1);path.pop_back();}}
};
七、矩阵最长递增路径
矩阵最长递增路径_牛客题霸_牛客网


dfs+记忆化搜索
#include <vector>
int memo[1001][1001],dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int _m,_n,ret;
class Solution {
public:int solve(vector<vector<int> >& matrix) {_m=matrix.size(),_n=matrix[0].size();for(int i=0;i<_m;++i){for(int j=0;j<_n;++j){ret=max(ret,dfs(matrix,i,j));}}return ret;}int dfs(vector<vector<int>>&matrix,int i,int j){if(memo[i][j])return memo[i][j];int path=1;for(int k=0;k<4;++k){int x=i+dx[k],y=j+dy[k];if(x>=0&&x<_m&&y>=0&&y<_n&&matrix[x][y]>matrix[i][j]){path=max(path,dfs(matrix,x,y)+1);}}memo[i][j]=path;return path;}
};
此篇完。
最轻松的一个专栏,*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。
