class Solution {
public:
vector<vector<int>> result; //存放符合条件结果的集合
vector<int> path; //存放符合条件的结果
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> used(nums.size(),false);
backtracking(nums,used);
return result;
}
void backtracking(vector<int>& nums,vector<bool>& used){
//终止条件
if(path.size()==nums.size()){
result.push_back(path);
return;
}
//遍历
for(int i=0;i<nums.size();i++){
//做选择
if(used[i]){
continue;
}
used[i]=true;
path.push_back(nums[i]);
//递归
backtracking(nums,used);
//撤销选择
path.pop_back();
used[i]=false;
}
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(int n,int k,int startIndex){
//终止条件
if(path.size()==k){
result.push_back(path);
return ;
}
//遍历
//-----------优化:for(int i=startIndex;i<=n-k+path.size()+1;i++)------------//
for(int i=startIndex;i<=n;i++){
//选择,处理节点
path.push_back(i);
//递归
backtracking(n,k,i+1);
//回溯,撤销处理的节点
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
backtracking(n,k,1);
return result;
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(int targetSum,int k,int sum,int startIndex){
//终止条件
if(path.size()==k){
if(sum==targetSum){
result.push_back(path);
return;
}
}
//遍历
for(int i=startIndex;i<=9;i++){
//选择
sum+=i;
path.push_back(i);
//递归
backtracking(targetSum,k,sum,i+1);
//回溯,撤销选择
sum-=i;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(n,k,0,1);
return result;
}
};
//剪枝优化
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(int targetSum,int k,int sum,int startIndex){
//终止条件
if(sum>targetSum){
return;
}
if(path.size()==k){
if(sum==targetSum){
result.push_back(path);
return;
}
}
//遍历
for(int i=startIndex;i<=10-k+path.size();i++){
//选择
sum+=i;
path.push_back(i);
//递归
backtracking(targetSum,k,sum,i+1);
//回溯,撤销选择
sum-=i;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(n,k,0,1);
return result;
}
};
class Solution {
private:
//映射
const string letterMap[10]={
"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"
};
public:
vector<string> result;
string path;
void bakctracking(const string& digits,int index){
//终止条件,digits里边遍历完就结束
if(digits.size()==index){
result.push_back(path);
return;
}
int digit=digits[index]-'0';
string letter=letterMap[digit];
//遍历:选择——递归——撤销选择(回溯)
for(int i=0;i<letter.size();i++){
path.push_back(letter[i]);
bakctracking(digits,index+1);
path.pop_back();
}
}
vector<string> letterCombinations(string digits) {
if(digits.size()==0){
return result;
}
bakctracking(digits,0);
return result;
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target,int sum,int startIndex){
//终止条件
if(sum>target){
return ;
}
if(target==sum){
result.push_back(path);
return;
}
//遍历:选择——递归——撤销选择(回溯)
for(int i=startIndex;i<candidates.size();i++){
sum+=candidates[i];
path.push_back(candidates[i]);
backtracking(candidates,target,sum,i);
sum-=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
};
///
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target,int sum,int startIndex){
//终止条件
if(sum>target){
return ;
}
if(target==sum){
result.push_back(path);
return;
}
//遍历:选择——递归——撤销选择(回溯)
//优化点:sum>target就没有必要继续递归了
for(int i=startIndex;i<candidates.size()&&sum+candidates[i]<=target;i++){
sum+=candidates[i];
path.push_back(candidates[i]);
backtracking(candidates,target,sum,i);
sum-=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
//剪枝优化需要排序
sort(candidates.begin(),candidates.end());
backtracking(candidates,target,0,0);
return result;
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target,int sum,int startIndex,vector<bool> used){
//终止条件
if(sum>target){
return;
}
if(sum==target){
result.push_back(path);
return ;
}
//遍历:选择——递归——撤销选择
for(int i=startIndex;i<candidates.size()&&sum+candidates[i]<=target;i++){
//去重,对同一层上已经使用过的元素进行跳过
//used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
//used[i - 1] == false,说明同一树层candidates[i - 1]使用过
if(i>0&&candidates[i-1]==candidates[i]&&used[i-1]==false){
continue;
}
sum+=candidates[i];
used[i]=true;
path.push_back(candidates[i]);
backtracking(candidates,target,sum,i+1,used);
sum-=candidates[i];
used[i]=false;
path.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
vector<bool> used(candidates.size(),false);
backtracking(candidates,target,0,0,used);
return result;
}
};
class Solution {
public:
vector<vector<string>> result;
vector<string> path;
void backtracking(const string& s,int startIndex){
//终止条件
if(startIndex>=s.size()){
result.push_back(path);
return;
}
//遍历:选择——递归——撤销选择
for(int i=startIndex;i<s.size();i++){
//选择:判断是否是回文
if(isPalindrome(s,startIndex,i)){
string str=s.substr(startIndex,i+1-startIndex);
path.push_back(str);
}else{
continue;
}
backtracking(s,i+1);
path.pop_back();
}
}
//双指针判断是否是回文
bool isPalindrome(const string& s,int start,int end){
for(int i=start,j=end;i<j;i++,j--){
if(s[i]!=s[j]){
return false;
}
}
return true;
}
vector<vector<string>> partition(string s) {
backtracking(s,0);
return result;
}
};
class Solution {
public:
vector<string> result;
void backtracking(string& s,int startIndex,int pointNum){
if(pointNum==3){ //已经分割好了,判断第四段是否合法
if(isValid(s,startIndex,s.size()-1)){
result.push_back(s);
}
return;
}
//遍历:选择——递归——撤销选择,回溯
for(int i=startIndex;i<s.size();i++){
if(isValid(s,startIndex,i)){
s.insert(s.begin()+i+1,'.');
pointNum++;
//递归时多了一个. 所以i+2
backtracking(s,i+2,pointNum);
pointNum--;
s.erase(s.begin()+i+1);
}else{
break;
}
}
}
bool isValid(const string& s,int start,int end){
if(start>end){
return false;
}
if(s[start]=='0'&&start!=end){ //以0开头不合法
return false;
}
int num=0;
for(int i=start;i<=end;i++){ //大于255不合法
if(s[i]>'9'||s[i]<'0'){
return false;
}
num=num*10+(s[i]-'0');
if(num>255){
return false;
}
}
return true;
}
vector<string> restoreIpAddresses(string s) {
if(s.size()>12){
return result;
}
backtracking(s,0,0);
return result;
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
//不漏掉自己
result.push_back(path);
//终止条件
if(startIndex>=nums.size()){
return;
}
//遍历:选择——递归——撤销选择、回溯
for(int i=startIndex;i<nums.size();i++){
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
backtracking(nums,0);
return result;
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex,vector<bool> used){
//终止条件,注意包含自身
result.push_back(path);
if(startIndex>=nums.size()){
return;
}
//遍历:选择——递归——撤销选择,注意去重
for(int i=startIndex;i<nums.size();i++){
if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false){
continue;
}
path.push_back(nums[i]);
used[i]=true;
backtracking(nums,i+1,used);
path.pop_back();
used[i]=false;
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<bool> used(nums.size(),false);
backtracking(nums,0,used);
return result;
}
};
//
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
//终止条件,注意包含自身
result.push_back(path);
unordered_set<int> uset; //在本层中去重
//遍历:选择——递归——撤销选择,注意去重,用set去重
for(int i=startIndex;i<nums.size();i++){
if(uset.find(nums[i])!=uset.end()){
continue;
}
uset.insert(nums[i]);
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
backtracking(nums,0);
return result;
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
//终止条件
if(path.size()>1){
result.push_back(path);
//不返回,要取全部节点
}
//遍历:选择——递归——取消选择、回溯,注意去重,用set
unordered_set<int> uset;
for(int i=startIndex;i<nums.size();i++){
//去重 非递增或重复时退出本次循环
if((uset.find(nums[i])!=uset.end())||!path.empty()&&nums[i]<path.back()){
continue;
}
uset.insert(nums[i]);
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtracking(nums,0);
return result;
}
};
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,vector<bool>& used){
//终止条件
if(path.size()==nums.size()){
result.push_back(path);
return;
}
//遍历:选择——递归——撤销选择、回溯
for(int i=0;i<nums.size();i++){
//去重
if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false){
continue;
}
if(used[i]==false){
used[i]=true;
path.push_back(nums[i]);
backtracking(nums,used);
path.pop_back();
used[i]=false;
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<bool> used(nums.size(),false);
sort(nums.begin(),nums.end());
backtracking(nums,used);
return result;
}
};
class Solution {
public:
// unordered_map<出发机场, map<到达机场, 航班次数>> targets
//航班次数+1、-1 因为有重复
unordered_map<string,map<string,int>> target;
int backtracking(int ticketNum,vector<string>& result){
//终止条件
if(result.size()==ticketNum+1){
return true;
}
//遍历:选择——递归——撤销选择、回溯
for(pair<const string,int>& tar:target[result[result.size()-1]]){
//还能往这个机场飞
if(tar.second>0){
result.push_back(tar.first);
tar.second--;
if(backtracking(ticketNum,result)){
return true;
}
result.pop_back();
tar.second++;
}
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> result;
//机场映射关系 初始化
for(const vector<string>& vec:tickets){
target[vec[0]][vec[1]]++;
}
result.push_back("JFK");
backtracking(tickets.size(),result);
return result;
}
};
class Solution {
public:
vector<vector<string>> result;
vector<int> path;
void backtracking(int n,int row,vector<string>& chessboard){
//终止条件
if(n==row){
result.push_back(chessboard);
return;
}
//遍历:选择——递归——撤销选择、回溯
for(int col=0;col<n;col++){
if(isValid(row,col,chessboard,n)){
chessboard[row][col]='Q';
backtracking(n,row+1,chessboard);
chessboard[row][col]='.';
}
}
}
bool isValid(int row,int col,vector<string>& chessboard,int n){
//不能同列
for(int i=0;i<row;i++){
if(chessboard[i][col]=='Q'){
return false;
}
}
//检查45度
for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
if(chessboard[i][j]=='Q'){
return false;
}
}
//检查135度
for(int i=row-1,j=col+1;i>=0&&j<n;i--,j++){
if(chessboard[i][j]=='Q'){
return false;
}
}
return true;
}
vector<vector<string>> solveNQueens(int n) {
vector<string> chessboard(n,string(n,'.'));
backtracking(n,0,chessboard);
return result;
}
};
class Solution {
public:
bool backtracking(vector<vector<char>>& board){
for(int i=0;i<board.size();i++){
for(int j=0;j<board[0].size();j++){
if(board[i][j]!='.'){
continue;
}
for(char k='1';k<='9';k++){
if(isValid(i,j,k,board)){
board[i][j]=k;
if(backtracking(board)){
return true;
}
board[i][j]='.';
}
}
return false;
}
}
return true;
}
bool isValid(int row,int col,char val,vector<vector<char>>& board){
//判断行里是否有重复
for(int i=0;i<board.size();i++){
if(board[i][col]==val){
return false;
}
}
//判断列里是否有重复
for(int j=0;j<board[0].size();j++){
if(board[row][j]==val){
return false;
}
}
//判断9宫格是否有重复
int rowStart=row/3*3;
int colStart=col/3*3;
for(int i=rowStart;i<rowStart+3;i++){
for(int j=colStart;j<colStart+3;j++){
if(board[i][j]==val){
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int result=0;
int m=grid.size(),n=grid[0].size();
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]=='1'){
result++;
dfs(grid,i,j);
}
}
}
return result;
}
void dfs(vector<vector<char>>& grid,int i,int j){
int m=grid.size(),n=grid[0].size();
if(i<0||i>=m||j<0||j>=n){
return;
}
if(grid[i][j]=='0'){
return;
}
grid[i][j]='0';//变为海水,避免再次遍历
dfs(grid,i-1,j);
dfs(grid,i+1,j);
dfs(grid,i,j-1);
dfs(grid,i,j+1);
}
};
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
int oldColor=image[sr][sc];
if(oldColor!=newColor){
dfs(image,sr,sc,oldColor,newColor);
}
return image;
}
void dfs(vector<vector<int>>& image,int i,int j,int oldColor,int newColor){
int m=image.size(),n=image[0].size();
if(i<0||i>=m||j<0||j>=n){
return;
}
if(image[i][j]!=oldColor){
return;
}
image[i][j]=newColor;
dfs(image,i,j-1,oldColor,newColor);
dfs(image,i,j+1,oldColor,newColor);
dfs(image,i-1,j,oldColor,newColor);
dfs(image,i+1,j,oldColor,newColor);
}
};
class Solution {
public:
int closedIsland(vector<vector<int>>& grid) {
int m=grid.size(),n=grid[0].size();
int result=0;
//靠边的岛屿不算封闭岛屿,先去掉
for(int i=0;i<m;i++){
dfs(grid,i,0);
dfs(grid,i,n-1);
}
for(int j=0;j<n;j++){
dfs(grid,0,j);
dfs(grid,m-1,j);
}
//剩下的都是封闭岛屿
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==0){
result++;
dfs(grid,i,j);
}
}
}
return result;
}
void dfs(vector<vector<int>>& grid,int i,int j){
int m=grid.size(),n=grid[0].size();
if(i<0||i>=m||j<0||j>=n){
return;
}
if(grid[i][j]==1){
return;
}
grid[i][j]=1;
dfs(grid,i-1,j);
dfs(grid,i+1,j);
dfs(grid,i,j-1);
dfs(grid,i,j+1);
}
};
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int m=grid.size(),n=grid[0].size();
int result=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==1){
result=max(result,dfs(grid,i,j));
}
}
}
return result;
}
int dfs(vector<vector<int>>& grid,int i,int j){
int m=grid.size(),n=grid[0].size();
if(i<0||i>=m||j<0||j>=n){
return 0;
}
if(grid[i][j]==0){
return 0;
}
grid[i][j]=0;
return dfs(grid,i-1,j)+dfs(grid,i+1,j)+dfs(grid,i,j-1)+dfs(grid,i,j+1)+1;
}
};
class Solution {
public:
int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
int m=grid1.size(),n=grid1[0].size();
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid1[i][j]==0&&grid2[i][j]==1){
//这个肯定不是岛屿,1中没有,2中有,淹没掉2
dfs(grid2,i,j);
}
}
}
//2中剩下的都是子岛
int result=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid2[i][j]==1){
result++;
dfs(grid2,i,j);
}
}
}
return result;
}
void dfs(vector<vector<int>>& grid, int i, int j){
int m=grid.size(),n=grid[0].size();
if(i<0||i>=m||j<0||j>=n){
return;
}
if(grid[i][j]==0){
return ;
}
grid[i][j]=0;
dfs(grid,i-1,j);
dfs(grid,i+1,j);
dfs(grid,i,j-1);
dfs(grid,i,j+1);
}
};