LeetCode随笔之BFS广度优先搜索

来源:互联网 发布:玻璃心 知乎 编辑:程序博客网 时间:2024/06/07 02:29
  1. (迷宫初级版)
  2. (迷宫进阶版)假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙
//这题就是普通的bfs多了‘钥匙’这个状态//所以book[x][y][key]的意义就是 横坐标为x,纵坐标为y,钥匙状态为key的点是否访问过//钥匙的状态 就用二进制数表示 最多10 把钥匙 那就是1024//比如我现在有第二把钥匙和第四把钥匙  那么我的钥匙状态就是 0101000000 也就是 320#include <iostream>#include <sstream>#include <string>#include <queue>#include <algorithm>#include <vector>#include <map>#include <bitset>using namespace std;bool book[105][105][1200];int NEXT[4][2]={0,1,0,-1,1,0,-1,0};struct node{    int x,y,key,step;    node(int x,int y, int key,int step):x(x),y(y),key(key),step(step){}};int bfs(int x1,int y1,vector<vector<char>> &G,int &m, int &n);int main(){    int n,m;    int x1,y1;    cin>>m>>n;        vector<vector<char>> G(m,vector<char> (n));        for(int i=0;i<m;i++){            for(int j=0;j<n;j++){                cin>>G[i][j];                if(G[i][j]=='2'){                    x1=i;y1=j;                }            }        }        int out=bfs(x1,y1,G,m,n);        cout<<out;    system("pause");    return 0;}int bfs(int x1,int y1,vector<vector<char>> &G,int &m, int &n){    book[x1][y1][0]=1;//表示是否走过    queue<node> Q;    Q.push(node(x1,y1,0,0));    while(!Q.empty()){        node head=Q.front();Q.pop();        if(G[head.x][head.y]=='3') return head.step;        for(int i=0;i<4;i++){            int nx=head.x+NEXT[i][0],ny=head.y+NEXT[i][1];            if(nx>=m||nx<0||ny>=n||ny<0||G[nx][ny]=='0') continue;            int key=head.key;            if('a'<=G[nx][ny]&&G[nx][ny]<='z') key=key|(1<<(G[nx][ny]-'a'));            if('A'<=G[nx][ny]&&G[nx][ny]<='Z'&&(key&(1<<(G[nx][ny]-'A')))==0) continue;            if(!book[nx][ny][key]){                book[nx][ny][key]=1;                Q.push(node(nx,ny,key,head.step+1));            }        }    }    return 0;}

3. 找到树每层最大值

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> largestValues(TreeNode* root) {        if(root==NULL) return vector<int>(0);        queue<TreeNode*> q;        q.push(root);        int i=0;        vector<int> maxValue;        while(!q.empty())        {            i++;            int k=q.size();            maxValue.push_back(findmax(q));            for(int j=0;j<k;j++)            {                TreeNode* f=q.front();                if(f->left) q.push(f->left);                if(f->right) q.push(f->right);                q.pop();            }        }        return maxValue;    }    int findmax(queue<TreeNode*> q)    {        queue<TreeNode*> q2=q;        int max=-2147483648;        while(!q2.empty())        {            TreeNode* tmp=q2.front();            q2.pop();            int tmpvalue=tmp->val;            max=tmpvalue>=max? tmpvalue:max;        }        return max;    }};

4. 求树的最小深度。

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; *//*DFS版本int minDepth(TreeNode* root) {    if (!root) return 0;    int L = minDepth(root->left), R = minDepth(root->right);    return 1 + (L && R ? min(L, R) : max(L, R)); }*/class Solution {public:    int minDepth(TreeNode* root) {        if (root == NULL) return 0;        queue<TreeNode*> Q;        Q.push(root);        int i=0;        while(!Q.empty())        {            i++;            int k=Q.size();            for(int j=0;j<k;j++)            {                TreeNode* rt=Q.front();                if(rt->left) Q.push(rt->left);                if(rt->right) Q.push(rt->right);                Q.pop();                if(rt->left==NULL && rt->right==NULL) return i;            }        }        return -1;    }};
  1. Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, …) which sum to n.

For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

//最复杂的思路,但是却通用。//也就是说,如果要求满足和为sum条件的有多少个,但是这种情况下4+9和9+4算做一种!!!注意!采用:for(int i=0;i<n;i++){    for(int j=sum;j>=A[i];j--){//倒叙为数不可重复使用,正序为可重复        dp[j]+=dp[j-A[i]];    }}//如果要求满足和为sum条件的,最少有几个数相加,则采用for(int i=0;i<n;i++){//同理正序可重复,倒叙不可重复!其实就是和从dp[sum]开始算起还是从dp[0]算起的区别。    for(int j=sum;j>=A[i];j--){        dp[j]=dp[j-A[i]]+1;    }}class Solution {public:    int numSquares(int m) {        int n=(int)sqrt((float)m);        vector<vector<int>> dp(m+1,vector<int> (m+1,0));        dp[0][0]=1;        vector<int> res;        for(int i=n;i>0;i--){            for(int k=1;k<=m;k++){                for(int j=i*i;j<=m;j++){                    dp[k][j]+=dp[k-1][j-i*i];//代表k个数相加且和为j的情况总共有多少种了。                }                if(dp[k][m]!=0) res.push_back(k);            }        }        int out=INT_MAX;        for(int i=0;i<res.size();i++)        {            out=min(res[i],out);        }        return out;    }};//简单点的思路:class Solution {public:    int numSquares(int m) {        int n=(int)sqrt((float)m);        //vector<vector<int>> dp(m+1,vector<int> (m+1,0));        vector<int> dp(m+1,0);        dp[0]=0;        vector<int> res;        for(int j=1;j<=m;j++){//分别就和为1...m,计算dp[j]在所有待选择数据中选择数据的个数            int minV=INT_MAX;            for(int i=1;i*i<=j;i++ ){                minV=min(minV,dp[j-i*i]+1);//dp[j]代表和为j,现在有几个数相加。                dp[j]=minV;            }        }        return dp[m];    }};
  1. Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.

The distance between two adjacent cells is 1.
Example 1:
Input:
0 0 0
0 1 0
1 1 1
Output:
0 0 0
0 1 0
1 2 1

//这种方法超时了...但是结果是对的。struct node{    int x,y;    int step;    node(int x,int y,int step):x(x),y(y),step(step) {}};class Solution {public:    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {        int m=matrix.size();int n=matrix[0].size();        int dir[4][2]={0,1,0,-1,1,0,-1,0};        for(int i=0;i<m;i++){            for(int j=0;j<n;j++){                if(matrix[i][j]!=0){                    vector<vector<int>> book(m,vector<int> (n,0));                    queue<node> Q;                    Q.push(node(i,j,0));                    while(!Q.empty()){                        node head=Q.front();Q.pop();                        if (matrix[head.x][head.y]==0)                             {matrix[i][j]=head.step;break;}                        for(int k=0;k<4;k++){                            int nx=head.x+dir[k][0];int ny=head.y+dir[k][1];                            if(nx<0||nx>=m||ny<0||ny>=n)continue;                            if(book[nx][ny]==0){                                book[nx][ny]=1;                                Q.push(node(nx,ny,head.step+1));                            }                        }                       }                }            }        }        return matrix;    }};//可以用动态规划来做,省心省力。class Solution {public:    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {        int h=matrix.size(), w=matrix[0].size();        vector<vector<int>> dp(h,vector<int>(w,INT_MAX));        for(int times=0;times<=1;times++) // two passes, first forward then backward            for(int i=times?h-1:0;times?i>=0:i<h;times?i--:i++)                 for(int j=times?w-1:0;times?j>=0:j<w;times?j--:j++)                        if(matrix[i][j]==0)                            dp[i][j]=0;                        else {                            if(i&&dp[i-1][j]!=INT_MAX&&dp[i][j]>dp[i-1][j]+1) // look up                                dp[i][j]=dp[i-1][j]+1;                            if(j&&dp[i][j-1]!=INT_MAX&&dp[i][j]>dp[i][j-1]+1) // look left                                dp[i][j]=dp[i][j-1]+1;                            if(i<h-1&&dp[i+1][j]!=INT_MAX&&dp[i][j]>dp[i+1][j]+1) // look down                                dp[i][j]=dp[i+1][j]+1;                            if(j<w-1&&dp[i][j+1]!=INT_MAX&&dp[i][j]>dp[i][j+1]+1) // look right                                dp[i][j]=dp[i][j+1]+1;                        }        return dp;    }};
原创粉丝点击