17. 电话号码的字母组合
dfs
class Solution {
public:
vector dict={
"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz",
};
vector letterCombinations(string digits) {
vectorres;
if(!digits.size())return res;
string tmp;
dfs(res,0,tmp,digits);
return res;
}
void dfs(vector&res,int k,string &tmp,string &digits){
int n=digits.size();
if(k>=n){
res.push_back(tmp);
return;
}
string mm=dict[digits[k]-'2'];
for(auto c:mm){
tmp+=c;
dfs(res,k+1,tmp,digits);
tmp.pop_back();
}
}
};
bfs
class Solution {
public:
vector dict={
"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz",
};
vector letterCombinations(string digits) {
vectorres;
if(!digits.size())return res;
queueq;
q.push("");
for(auto c:digits){
int n=q.size();
for(int i=0;i
79. 单词搜索
class Solution {
public:
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
bool exist(vector>& board, string word) {
int n=board.size(),m=board[0].size();
vector>vis(n,vector(m));
for(int i=0;i>& board,int t,string &word,vector>&vis){
if(board[i][j]!=word[t])return false;
if(t>=word.size()-1) return true;
int n=board.size(),m=board[0].size();
vis[i][j]=true;
for(int k=0;k<4;k++){
int a=i+dx[k],b=j+dy[k];
if(a>=0 && a=0 && b
y总写的,这样就不用多一个vis
数组判断是否访问过了%%。
直接把访问过的board[i][j]
改为'.',总之就是一个不会合法出现在board
数组里的元素
class Solution {
public:
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
bool exist(vector>& board, string word) {
int n=board.size(),m=board[0].size();
for(int i=0;i>& board,int t,string &word){
if(board[i][j]!=word[t])return false;
if(t>=word.size()-1) return true;
int n=board.size(),m=board[0].size();
board[i][j]='.';
for(int k=0;k<4;k++){
int a=i+dx[k],b=j+dy[k];
if(a>=0 && a=0 && b
46. 全排列
非字典序,代码量较少的写法
class Solution {
public:
vector> permute(vector& nums) {
vector> res;
dfs(res,0,nums);
return res;
}
void dfs(vector> &res,int k,vector& nums){
if(k==nums.size()) res.push_back(nums);
for(int i=k;i
字典序写法
class Solution {
public:
vector> permute(vector& nums) {
vector> res;
vectorused(nums.size());
vectortmp;
dfs(res,0,nums,tmp,used);
return res;
}
void dfs(vector> &res,int k,vector& nums,vector&tmp,vector &used){
if(k==nums.size()) res.push_back(tmp);
for(int i=0;i
害!辣个蓝人代码量总是比我少一点,我的代码里dfs参数太多了。
class Solution {
public:
vectorpath;
vector used;
vector> permute(vector& nums) {
vector> res;
int n=nums.size();
used=vector(n);
dfs(res,0,nums);
return res;
}
void dfs(vector> &res,int k,vector& nums){
if(k==nums.size()) res.push_back(path);
for(int i=0;i
78. 子集
dfs
class Solution {
public:
vector>res;
vectortmp;
int n;
vector> subsets(vector& nums) {
n=nums.size();
dfs(0,nums);
return res;
}
void dfs(int k,vector& nums){
if(k>=n) {
res.push_back(tmp);
return;
}
tmp.push_back(nums[k]);
dfs(k+1,nums);
tmp.pop_back();
dfs(k+1,nums);
}
};
位运算做法
优点:快
缺点:递归深度不能超过int(32)
class Solution {
public:
vector>res;
vectortmp;
int n;
vector> subsets(vector& nums) {
n=nums.size();
for(int i=0;i<1<tmp;
for(int j=0;j>j & 1)
tmp.push_back(nums[j]);
}
res.push_back(tmp);
}
return res;
}
};
90. 子集 II
分别用0~k次
第一次for(i=0),用了0次当前数
第二次for(i=1),用了1次当前数
...
第k+1次for(i=k),用了k次当前数
dfs是u+k
层的原因:nums[u+k]
就是下一个数了
class Solution {
public:
vector>res;
vectorpath;
vector> subsetsWithDup(vector& nums) {
sort(nums.begin(),nums.end());
dfs(nums,0);
return res;
}
void dfs(vector&nums,int u){
if(u==nums.size()){
res.push_back(path);
return ;
}
// 计算 当前数字的个数
int k=0;
while(u+k
216. 组合总和 III
一定要在for枚举选择里添加,和恢复现场
class Solution {
public:
vector>res;
vectorpath;
vector> combinationSum3(int k, int n) {
dfs(0,0,1,k,n);
return res;
}
void dfs(int u,int sum,int cur,int &k,int &n){
if(u==k){
if(sum==n)res.push_back(path);
return ;
}
if(sum>n)return ;
for(int i=cur;i<=9;i++){
sum+=i;
path.push_back(i);
dfs(u+1,sum,i+1,k,n);
sum-=i;
path.pop_back();
}
}
};
害!辣个蓝人的代码还是比我简洁。。参数列表里少了u
和sum
class Solution {
public:
vector>res;
vectorpath;
vector> combinationSum3(int k, int n) {
dfs(1,k,n);
return res;
}
void dfs(int cur,int k,int n){
if(!k){
if(!n)res.push_back(path);
return ;
}
for(int i=cur;i<=9;i++){
path.push_back(i);
dfs(i+1,k-1,n-i);
path.pop_back();
}
}
};
52. N皇后 II
这尼玛也太吊了。就这几行
灵魂是:
- 从左上到右下的斜线x-y都相等
- 从右上到左下的斜线x+y都相等
class Solution {
public:
int ans=0,n;
vectorcol,diag,udiag;
int totalNQueens(int _n) {
n=_n;
col=vector(n);
diag=vector(2*n);
udiag=vector(2*n);
dfs(0);
return ans;
}
void dfs(int u){
if(u==n){
ans++;
return;
}
// u是层数,i是列数
for(int i=0;i
37. 解数独
太吊了,和上面的八皇后一个思路
class Solution {
public:
bool row[9][9],col[9][9],cell[3][3][9];
void solveSudoku(vector>& board) {
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
if(board[i][j]!='.'){
int t=board[i][j]-'1';
row[i][t]=col[j][t]=cell[i/3][j/3][t]=true;
}
dfs(0,0,board);
}
bool dfs(int x,int y,vector>& board){
if(y==9)x++,y=0;
if(x==9)return true;
// 相当于剪枝
if(board[x][y]!='.')return dfs(x,y+1,board);
for(int i=0;i<9;i++){
if(!row[x][i] && !col[y][i] && !cell[x/3][y/3][i]){
row[x][i]=col[y][i]=cell[x/3][y/3][i]=true;
board[x][y]=i+'1';
if(dfs(x,y,board))return true;
row[x][i]=col[y][i]=cell[x/3][y/3][i]=false;
board[x][y]='.';
}
}
return false;
}
};
473. 火柴拼正方形
之前好像是自己写的吧。。害挺聪明
class Solution {
public:
vector vis;
bool dfs(vector &nums, int i, int target, int cur_sum) {
if (cur_sum == target) return true;
for (int j = i; j < nums.size(); j++) {
if (!vis[j] && nums[j] + cur_sum <= target) {
vis[j] = true;
if (dfs(nums, j, target, cur_sum + nums[j])) return true;
vis[j] = false;
}
}
return false;
}
bool makesquare(vector &nums) {
if (nums.size() < 4) return false;
// 从大到小排序
sort(nums.rbegin(), nums.rend());
vis = vector(nums.size(), false);
int sum = 0, target;
for (int num : nums) sum += num;
if (sum % 4) return false;
target = sum / 4;
int i=0;
for (int j = 0; j < 4; j++) {
while (vis[i]) i++;
if (!dfs(nums, i, target, 0)) return false;
}
return true;
}
};
这么多剪枝记不太住啊
class Solution {
public:
vectorused;
bool makesquare(vector& nums) {
int sum=0;
for(auto i :nums)sum+=i;
if(!sum || sum%4)return false;
used=vector(nums.size());
sort(nums.rbegin(),nums.rend());
return dfs(nums,0,0,sum/4);
}
bool dfs(vector&nums,int u,int cur,int length){
if(cur==length)u++,cur=0;
if(u==4)return true;
for(int i=0;i