216 组合总和Ⅲ
class Solution {
public:
vector<vector<int>> res;
vector<int> group;
int Sum=0;
void func(int k,int n,int start)
{
if(Sum>n)return;
if(group.size()==k)
{
if(Sum==n) res.push_back(group);
return;
}
for(int i=start;i<=9-(k-group.size())+1;++i)
{
Sum+=i;
group.push_back(i);
func(k,n,i+1);
Sum-=group.back();
group.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
res.clear();
group.clear();
func(k,n,1);
return res;
}
};
17 电话号码的字母组合
class Solution {
public:
const string Str[11]=
{
"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz",""
};
vector<string> res;
string piece;
int index=0; //len=edigits.size()时匹配一次完成
void func(string str,int index) //str 数字
{
if(index==str.size())
{
res.push_back(piece);
return;
}
int digit=str[index]-'0';
string substr=Str[digit];
for(auto elem:substr)
{
piece.push_back(elem);
func(str,index+1);
piece.pop_back();
// --index;
}
}
vector<string> letterCombinations(string digits) {
string edigits;
for(auto elem:digits)
{
if(elem=='2'||elem=='3'||elem=='4'||elem=='5'||elem=='6'||elem=='7'||elem=='8'||elem=='9')
{
edigits.push_back(elem);
}
}
//edigits 有效数字2~9
res.clear();
piece.clear();
if(edigits.size()==0) return res;
func(edigits,0);
return res;
}
};
39 组合总和
class Solution {
public:
vector<vector<int>> res;
vector<int> group;
int Sum=0;
void func(vector<int>& nums,int& target)
{
if(Sum>=target)
{
if(Sum==target)res.push_back(group);
// Sum-=nums[i];
// group.pop_back();
return;
}
for(int i=0;i<nums.size();++i)
{
if(group.size()==0 || (group.size()>=1 && nums[i]>=group.back() ) )
{
Sum+=nums[i];
group.push_back(nums[i]);
func(nums,target);
Sum-=nums[i];
group.pop_back();
}
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());//递增序列
res.clear();
group.clear();
func(candidates,target);
return res;
}
};
40 组合总和Ⅱ
class Solution {
public:
vector<vector<int>> res;
vector<int> group;
int Sum;
void func(vector<int>& candidates,int target,int index,vector<bool>& bUsed)
{
if(Sum>=target)
{
if(Sum==target) res.push_back(group);
return;
}
for(int i=index;i<candidates.size();++i)
{
if(i>0 && (candidates[i]==candidates[i-1]&&bUsed[i-1]==false) ) continue;
Sum+=candidates[i];
group.push_back(candidates[i]);
bUsed[i]=true;
func(candidates,target,i+1,bUsed);
Sum-=candidates[i];
group.pop_back();
bUsed[i]=false;
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
res.clear();
group.clear();
vector<bool> bUsed(candidates.size(),false);
func(candidates,target,0,bUsed);
return res;
}
};
131 分割回文串
class Solution {
public:
vector<vector<string>> res;
vector<string> group;
bool IsStr(string str)
{
int i=0,j=str.size()-1;
while(i<=j)
{
if(str[i]!=str[j]) return false;
++i;
--j;
}
return true;
}
void func(string s,int index)
{
if(index>=s.size())
{
res.push_back(group);
return;
}
for(int i=index;i<s.size();++i)
{
if(IsStr(s.substr(index,i-index+1))) group.push_back(s.substr(index,i-index+1));
else continue;
func(s,i+1);
group.pop_back();
}
}
vector<vector<string>> partition(string s) {
res.clear();
group.clear();
func(s,0);
return res;
}
};
93 复原IP地址
class Solution {
public:
vector<string> res;
vector<string> ip;
bool UnitCheck(string str)
{
if(str[0]=='0'&&str.size()>1) return false;
int a=atoi(str.c_str());
if(a<0||a>255) return false;
return true;
}
string ProcessIp(vector<string> ip)
{
string str;
str+=ip[0];str+=".";
str+=ip[1];str+=".";
str+=ip[2];str+=".";
str+=ip[3];
return str;
}
void func(string s,int index)
{
if(ip.size()==4
&&ip[0].size()+ip[1].size()+ip[2].size()+ip[3].size()==s.size())
{
string str=ProcessIp(ip);
res.push_back(str);
return;
}
for(int i=index;i<s.size();++i)
{
if(UnitCheck(s.substr(index,i-index+1)))
{
ip.push_back(s.substr(index,i-index+1));
}
else
{
continue;
}
func(s,i+1);
ip.pop_back();
}
}
vector<string> restoreIpAddresses(string s) {
res.clear();
ip.clear();
func(s,0);
return res;
}
};
78 子集
class Solution {
public:
vector<vector<int>> res;
vector<int> group;
void func(vector<int>& nums,int iStart)
{
res.push_back(group);
if(iStart==nums.size())
{
return;
}
for(int i=iStart;i<nums.size();++i)
{
group.push_back(nums[i]);
func(nums,i+1);
group.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
res.clear();
group.clear();
sort(nums.begin(),nums.end());
func(nums,0);
//res.push_back(vector<int>{});
return res;
}
};
90 子集Ⅱ
class Solution {
public:
vector<vector<int>> res;
vector<int> group;
void func(vector<int>& nums,vector<bool>& bVisited,int iStart)
{
res.push_back(group);
for(int i=iStart;i<nums.size();++i)
{
if(i>0&&nums[i]==nums[i-1]&&bVisited[i-1]==false) continue;
//[i-1]曾作为叶子节点回溯后等值曾作为上层节点,所以同层不必再从此往下取值
group.push_back(nums[i]);
bVisited[i]=true;
func(nums,bVisited,i+1);
bVisited[i]=false;
group.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<bool> bVisited(nums.size(),false);
sort(nums.begin(),nums.end());
//for(auto elem:nums) cout<<elem<<" ";
res.clear();
group.clear();
func(nums,bVisited,0);
return res;
}
};
46 全排列
class Solution {
public:
vector<vector<int>> res;
vector<int> group;
void fun(vector<int>& nums,vector<bool>& bVisited)
{
if(group.size()==nums.size())
{
res.push_back(group);
return;
}
for(int i=0;i<nums.size();++i)
{
if(bVisited[i]==true) continue;
group.push_back(nums[i]);
bVisited[i]=true;
fun(nums,bVisited);
bVisited[i]=false;
group.pop_back();
}
}
vector<vector<int>> permute(vector<int>& nums) {
res.clear();
group.clear();
vector<bool> bVisited(nums.size(),false);
fun(nums,bVisited);
return res;
}
};
对递归的过程可以在纸上画一画,clam down and follow the process , you would figure it out!
47 全排列Ⅱ
class Solution {
public:
vector<vector<int>> res;
vector<int> group;
void func(vector<int>& nums,vector<bool>& bVisited)
{
if(group.size()==nums.size()) {
res.push_back(group);
return;
}
for(int i=0;i<nums.size();++i)
{
if(bVisited[i]==true) continue;
if(i>0&&nums[i]==nums[i-1]&&bVisited[i-1]==false) continue;
//bVisited[i-1]==true也能通过?
//《代码随想录》 树枝去重与树层去重
//[1.1.2] [0]-[1]->continue;
//[1]-[0]-[2] push_bacK(group);
group.push_back(nums[i]);
bVisited[i]=true;
func(nums,bVisited);
group.pop_back();
bVisited[i]=false;
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
res.clear();
group.clear();
sort(nums.begin(),nums.end());
vector<bool> bVisited(nums.size(),false);
func(nums,bVisited);
return res;
}
};
51 N皇后问题
class Solution {
public:
vector<vector<string>> res;
vector<string> sol;
void InitChessBoard(vector<string>& sol,int n)
{
string row;
for(int i=0;i<n;++i) row.push_back('.');
for(int i=0;i<n;++i) sol.push_back(row);
}
void Place(vector<string>& sol,vector<vector<bool>>& bFull,int i,int j,int n)
{
sol[i][j]='Q';
bFull[0][i]=true;
bFull[1][j]=true;
bFull[2][(i+j)]=true;
bFull[3][(i-j+n-1)]=true;
}
void Remove(vector<string>& sol,vector<vector<bool>>& bFull,int i,int j,int n)
{
sol[i][j]='.';
bFull[0][i]=false;
bFull[1][j]=false;
bFull[2][(i+j)]=false;
bFull[3][(i-j+n-1)]=false;
}
bool Check(vector<vector<bool>>& bFull,int i,int j,int n)
{
if(bFull[0][i]==true) return false;//行
if(bFull[1][j]==true) return false;//列
if(bFull[2][(i+j)]==true) return false;//正斜 /
if(bFull[3][(i-j+n-1)]==true) return false;//反斜
return true;
}
void func(vector<string>& sol,int n,int iRow,vector<vector<bool>>& bFull)
{
// cout<<"hello"<<endl;
// for(auto elem:sol)
// {
// cout<<elem<<endl;
// }
// for(auto row:bFull)
// {
// for(auto elem:row)
// {
// cout<<elem<<" ";
// }
// cout<<endl;
// }
if(iRow==n)
{
res.push_back(sol);
return;
}
for(int i=0;i<n;++i) //各列
{
if(Check(bFull,iRow,i,n)){
Place(sol,bFull,iRow,i,n);
func(sol,n,iRow+1,bFull);
Remove(sol,bFull,iRow,i,n);
}
}
//如果这行填过就到下一行
if(sol[iRow][n-1]=='Q')
{
func(sol,n,iRow+1,bFull);
}
}
vector<vector<string>> solveNQueens(int n) {
res.clear();
sol.clear();
InitChessBoard(sol,n);//[0]行, [1]-[n]行的[0]列为棋盘边界
vector<bool> bPlaced1(n,false);
vector<bool> bPlaced2(2*n-1,false);
vector<vector<bool>> bFull;
for(int i=0;i<2;++i) bFull.push_back(bPlaced1);//行、列
//正斜\反斜
for(int i=2;i<4;++i) bFull.push_back(bPlaced2);
func(sol,n,0,bFull);
return res;
}
};