一、dfs剪枝
1、字符串的排列
题目描述:
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
代码如下:
class Solution {
public:
vector<string> permutation(string s) {
vector<string>res;
string str;
vector<int>visited(s.size(),0);
dfs(res,str,s,0,visited);
return res;
}
void dfs(vector<string>&res,string str,string s,int cur,vector<int>visited){
if(cur==s.size()){
res.push_back(str);
return;
}
for(int i=0;i<s.size();i++){
if(visited[i]) continue;//剪枝,遍历过的数不再遍历
if(i>0&&s[i]==s[i-1]&&!visited[i-1]) continue;//剪枝,重复元素不再遍历
str+=s[i];
visited[i]=1;
dfs(res,str,s,cur+1,visited);
visited[i]=0;
str.pop_back();
}
}
};
2、递增子序列
题目描述:
给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是 2 。
代码如下:
class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
set<vector<int>>res;
vector<int>temp;
dfs(0,nums,res,temp);
return vector<vector<int>>(res.begin(),res.end());
}
void dfs(int cur,vector<int>&nums,set<vector<int>>&res,vector<int>temp){
if(temp.size()>=2){
res.insert(temp);
}
for(int i=cur;i<nums.size();i++){
if(!temp.empty()&&nums[i]<temp.back()) continue;
temp.push_back(nums[i]);
dfs(i+1,nums,res,temp);
temp.pop_back();
}
}
};
3、leetcode 46 全排列
题目描述:
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
代码如下:
class Solution {
public:
void dfs(vector<int>&nums,vector<vector<int>>&res,vector<int>&temp,vector<int>&visited){
if(temp.size()==nums.size()){
res.push_back(temp);
return;
}
for(int i=0;i<nums.size();i++){
if(visited[i]) continue;
if(i>0&&nums[i-1]==nums[i]&&!visited[i]) continue;
temp.push_back(nums[i]);
visited[i]=1;
dfs(nums,res,temp,visited);
temp.pop_back();
visited[i]=0;
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>>res;
vector<int>temp;
vector<int>visited(nums.size(),0);
dfs(nums,res,temp,visited);
return res;
}
};
4、剑指 Offer 34. 二叉树中和为某一值的路径
题目描述:
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int target) {
vector<vector<int>>res;
vector<int>path;
dfs(res,path,0,root,target);
return res;
}
void dfs(vector<vector<int>>&res,vector<int>&path,int sum,TreeNode* root,int target){
if(!root) return;
sum+=root->val;
path.push_back(root->val);
if(sum==target&&!root->left&&!root->right) res.push_back(path);
dfs(res,path,sum,root->left,target);
dfs(res,path,sum,root->right,target);
path.pop_back();
}
};
二、bfs
1、题目描述:leetcode 1091 二进制矩阵中的最短路径
思路:bfs
代码如下:
class Solution {
public:
vector<vector<int>>dir={{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
if(grid[0][0]==1) return -1;
int n=grid.size();
int m=grid[0].size();
if(n==1&&m==1&&grid[0][0]==0) return 1;
int res=2;
queue<pair<int,int>>q;
q.push(make_pair(0,0));
while(!q.empty()){
int k=q.size();
for(int i=0;i<k;i++){
int x=(q.front()).first;
int y=(q.front()).second;
q.pop();
for(int j=0;j<dir.size();j++){
int a=x+dir[j][0];
int b=y+dir[j][1];
if(a>=0&&a<n&&b>=0&&b<m&&grid[a][b]==0){
if(a==n-1&&b==m-1) return res;
else{
q.push(make_pair(a,b));
}
grid[a][b]=1;//走过的不再走
}
}
}
res++;
}
return -1;
}
};
2、题目描述:leetcode 815 公交路线
思路:dfs+map
代码如下:
class Solution {
public:
int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
if(source==target) return 0;
int n=routes.size();
vector<bool>visited(n,false);
unordered_map<int,vector<int>>mp;
queue<int>q;
for(int i=0;i<routes.size();i++){
for(int j=0;j<routes[i].size();j++){
mp[routes[i][j]].push_back(i);
}
}
int res=0;
q.push(source);
while(!q.empty()){
res++;
int s=q.size();
for(int i=0;i<s;i++){
int t=q.front();
q.pop();
for(int j:mp[t]){
if(!visited[j]){
for(int num:routes[j]){
if(num==target) return res;
q.push(num);
}
visited[j]=true;
}
}
}
}
return -1;
}
};