leetcode dfs剪枝以及bfs

一、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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值