目录

  • 岛屿数目!!!
  • 包围区域!!!
  • 矩阵里搜索单词
  • 拷贝图
  • 太平洋大西洋出海口
  • 最长增长路径!!!
  • 单词接龙
  • 课表问题1
  • 课表问题2

二叉树里已经大量使用了DFS,BFS,二叉树的前序遍历,中序遍历 后序遍历就是DFS,层序遍历
就是BFS。
对于二叉树这种具有单向分层结构,进行DFS BFS时无需担心会重复访问,但是对于无向图或者
有向有环图等结构,需要使用辅助数据结构来记录当前节点是否已经访问过。

岛屿数目!!!

class Solution {int m=0;int n=0;//DFS解法void mark_island_dfs(int i,int j,vector<vector<char>>& grid){grid[i][j] = 'a';//设定访问标志if(i-1>=0 && grid[i-1][j]=='1' ) mark_island1_dfs(i-1,j,grid);if(i+1<m && grid[i+1][j]=='1' ) mark_island1_dfs(i+1,j,grid);if(j-1>=0 && grid[i][j-1]=='1' ) mark_island1_dfs(i,j-1,grid);if(j+1<n && grid[i][j+1]=='1' ) mark_island1_dfs(i,j+1,grid);}
public:int numIslands(vector<vector<char>>& grid) {if(grid.empty()) return 0;m=grid.size();n=grid[0].size();//mark all point's of a same island as visited;int island_num=0;  for(int i=0;i<m;++i){for(int j=0;j<n;++j){//find a seed of a islandif(grid[i][j]=='1' ){++island_num;mark_island_dfs(i,j,grid);}  }}return island_num;}
};

包围区域!!!

先将所有与边缘连通的O标记为其他字符Y,在将剩余O翻转为X。最后恢复Y

class Solution {void mark_dfs(int i,int j,vector<vector<char>>& board){vector<int>x_directions={i,i,i-1,i+1};vector<int>y_directions={j-1,j+1,j,j};for(int k=0;k<4;++k){int x=x_directions[k];int y=y_directions[k];if(x>=0 && y>=0 && x<board.size() && y<board[0].size()){if(board[x][y] == 'O'){board[x][y]='Y';mark_dfs(x,y,board);}}}}public:void solve(vector<vector<char>>& board) {//将所有与边缘联通的O 标记为Yif(board.size()<=1) return;int m=board.size();int n=board[0].size();for(int i=0;i<m;++i){if(board[i][0] == 'O'){board[i][0]='Y';mark_dfs(i,0,board);}if(board[i][n-1]=='O'){board[i][n-1]='Y';mark_dfs(i,n-1,board);}}for(int i=0;i<n;++i){if(board[0][i] == 'O'){board[0][i]='Y';mark_dfs(0,i,board);}if(board[m-1][i]=='O'){board[m-1][i]='Y';mark_dfs(m-1,i,board);}}for(int i=0;i<m;++i){for(int j=0;j<n;++j){if(board[i][j]=='O') board[i][j]='X';if(board[i][j]=='Y') board[i][j]='O';}}      }
};

矩阵里搜索单词

经典的四向搜索问题。

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3bool backTrak(const vector<vector<char> > &board , const string& word, int row , int col,int pos,vector<vector<bool> >& record)
{if(row >= board.size() || row < 0 )return false;if(col >= board[row].size() || col < 0) return false;if( board[row][col] == word[pos] && pos <= word.size()-1){record[row][col] = true;if(pos == word.size()-1 ) return true;if(row+1 < board.size() && false == record[row+1][col] && backTrak(board ,  word,  row+1 ,  col, pos+1,record)) return true;else if(row-1 >= 0 && false == record[row-1][col] && backTrak(board ,  word,  row-1 ,  col, pos+1,record)) return true;else if(col+1 < board[row].size() && false == record[row][col+1]&& backTrak(board , word,  row , col+1, pos+1,record))return true;else if(col-1 >=0 && false == record[row][col-1] && backTrak(board ,  word,  row ,  col-1, pos+1,record)) return true;}record[row][col] = false;return false;
}class Solution {public:bool exist(vector<vector<char> > &board, string word) {if(word.size() == 0 )return false;vector<vector<bool> > record(board.size(),vector<bool>(board[0].size(),false));for(int i = 0 ; i < board.size() ; i++){for(int j = 0 ; j < board[i].size() ; j++){if( backTrak(board ,  word,  i, j, 0,record) ) return true;}              }return false;        }
};

拷贝图

可以利用map同时起到判断是否第一次访问,以及记录当前节点的拷贝节点的地址的作用。

class Solution {map<int,Node*>copys;
public:Node* cloneGraph(Node* node) {if(node==NULL) return NULL;Node*pCurr=NULL;   //第一次访问当前节点,则拷贝一份该节点,并将其子节点放入。if(copys.count(node->val)==0){pCurr=new Node(node->val);copys[node->val]=pCurr;for(auto child:node->neighbors){pCurr->neighbors.push_back(cloneGraph(child));}}else{pCurr=copys.find(node->val)->second;}   return pCurr;
}};

太平洋大西洋出海口

分别标记能流入太平洋的位置以及能流入大西洋位置。二者均能流入则为所求

class Solution {//<i,j>为出海口,将所有可流入该出海口点标记为1void dfs_ocean(int i,int j,vector<vector<int>>&ocean,vector<vector<int>>& matrix){// 四个方向int direction_x[4]={i,i,i-1,i+1};int direction_y[4]={j-1,j+1,j,j};for(int k=0;k<4;++k){int x=direction_x[k];int y=direction_y[k];if(x>=0&&x<ocean.size()&&y>=0&&y<ocean[0].size()&&matrix[i][j]<=matrix[x][y] && ocean[x][y]==0){ocean[x][y]=1;dfs_ocean(x,y,ocean,matrix);}}}public:vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {vector<vector<int>>ret;if(matrix.empty()) return ret;int m=matrix.size();int n=matrix[0].size();//find if flow to pacific//0 unsure , 1 can flow to pacific,-1 can not flow to pacificvector<vector<int>> pacific(m,vector<int>(n,0));auto atlantic=pacific;//初始化所有出海口for(int i=0;i<m;++i){pacific[i][0]=1;atlantic[i][n-1]=1;}for(int i=0;i<n;++i){pacific[0][i]=1;atlantic[m-1][i]=1;}for(int i=0;i<m;++i){dfs_ocean(i,0,pacific,matrix);dfs_ocean(i,n-1,atlantic,matrix);}for(int i=0;i<n;++i){dfs_ocean(0,i,pacific,matrix);dfs_ocean(m-1,i,atlantic,matrix);}       for(int i=0;i<m;++i){for(int j=0;j<n;++j){if(pacific[i][j]==1 && atlantic[i][j]==1){vector<int>r={i,j};ret.push_back(r);}}}return ret;      }
};

最长增长路径!!!

对每个位置,访问比自己大的邻接点,并且更新从当前位置出发能达到的最大增长长度

class Solution {vector<vector<int>>mark;int dfs(int i,int j,vector<vector<int>>&mark,const vector<vector<int>>&matrix){int m=matrix.size();int n=matrix[0].size();if(mark[i][j]==0){vector<int> delta_x={-1,1,0,0};vector<int> delta_y={0,0,1,-1};mark[i][j]=1;for(int k=0;k<4;++k){int x=i+delta_x[k];int y=j+delta_y[k];if(x>=0&&x<m&&y>=0&&y<n&&matrix[x][y]>matrix[i][j]){if(mark[x][y]==0){mark[i][j]=max(mark[i][j], dfs(x,y,mark,matrix)+1);}else{mark[i][j]=max(mark[i][j],mark[x][y]+1);}}}}return mark[i][j];}public:int longestIncreasingPath(vector<vector<int>>& matrix) {if(matrix.empty()) return 0;mark.resize(matrix.size(),vector<int>(matrix[0].size(),0));int ret=0;for(int i=0;i<matrix.size();++i){for(int j=0;j<matrix[0].size();++j){ret=max(ret,dfs(i,j,mark,matrix));}}return ret;}
};

单词接龙

通过BFS按层遍历,思路比较直接

void getNextWords(const string &currWord ,  queue<string>& nextLayer ,unordered_set<string>& wordDict)
{for(int i = 0 ; i < currWord.size() ;++i)  //生产新单词策略是遍历整个单词,并且依次将该单词各个字符变换为26个字母中其他字符,再{                                          //在字典中查找该单词是否存在string temp = currWord;for(char c = 'a' ; c <='z' ;++c){if(c != currWord[i]){temp[i] = c;if(1 == wordDict.count(temp)){nextLayer.push(temp);wordDict.erase(temp);}}}}
}class Solution {public:int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {auto myDict = wordDict;queue<string>currLayer , nextLayer;int nLayer = 0;currLayer.push(beginWord);++nLayer ;string currWord;while(true) //广度优先搜索{while(!currLayer.empty()){currWord = currLayer.front();getNextWords(currWord , nextLayer,myDict);//将当前单词可推导出的且尚未使用的词汇加入下一层currLayer.pop();}if(nextLayer.empty()) return 0; //无法推导出最终词汇++nLayer;while(!nextLayer.empty()){currWord = nextLayer.front();if(currWord == endWord) return nLayer; //检查最终词汇是否已经被推导出来currLayer.push(currWord);nextLayer.pop();}}}
};

课表问题1

本质是寻找一个图里是否有环
构建图可以使用邻接矩阵等多种方式,以下代码为简单,直接使用数组记录一个节点的父节点和子节点。
BFS判断是否有环方法:
访问一个节点时,只有其所有父节点已经被访问过,才访问当前节点。从而保证不会访问成环。
此处每次访问某节点时,更新其子节点里记录父节点被访问的个数。
最终如果所有节点均被访问到,证明图里不存在环。

DFS判断是否有环方法:
记录当前路径上被访问的序列,如果发现当前节点的子节点已经被访问,则证明存在环。

struct Node{int c;vector<int>pres;vector<int>nexts;
};class Solution {bool bfs_no_loop(vector<Node>&graph){vector<bool>visited(graph.size(),false);queue<Node*>q;vector<int>pres_visited_num(graph.size(),0);for(int i=0;i<graph.size();++i){if(graph[i].pres.size()==0){visited[i]=true;for(auto child:graph[i].nexts){++pres_visited_num[child];q.push(&graph[child]);}}}while(!q.empty()){auto curr=q.front();q.pop();if(visited[curr->c]==false && pres_visited_num[curr->c]==curr->pres.size()){visited[curr->c]=true;for(auto child:curr->nexts){if(!visited[child]){++pres_visited_num[child];q.push(&graph[child]);}}}}for(auto v:visited){if(!v) return false;}return true;}vector<bool>visited;bool dfs_no_loop(Node&root,vector<Node>&tree,vector<bool>&visited,vector<bool>&curr_path_visit){//叶子节点if(root.nexts.size()==0) return true;else{for(auto child:root.nexts){if(visited[child]) continue;//父节点出现在后继中,即存在环if(curr_path_visit[child] == true) return false;else{curr_path_visit[child]=true;if(!dfs_no_loop(tree[child],tree,visited,curr_path_visit)){return false;}else{visited[child]=true; }curr_path_visit[child]=false;}}}return true;}
public:bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {if(numCourses ==0) return true;visited.resize(numCourses,false);vector<Node>tree(numCourses);for(int i=0;i<tree.size();++i)tree[i].c=i;for(auto &pre:prerequisites){tree[pre[0]].pres.push_back(pre[1]);tree[pre[1]].nexts.push_back(pre[0]);}///use bfs ------return bfs_no_loop(tree);for(auto &r:tree){//无前继则为某可子树的根节点if(r.pres.size()==0){vector<bool>curr_path_visit(tree.size(),false);curr_path_visit[r.c]=true;if(!dfs_no_loop(r,tree,visited,curr_path_visit)){return false;}else{visited[r.c]=true;}}}for(auto i:visited){if(!i) return false;}return true;}
};

课表问题2

采用课表1中的BFS方法,访问所有节点,其顺序即为可行的上课顺序

struct Node{int pres_num=0;vector<int>childs;
};vector<int>BFS(vector<Node>&graph){queue<int>q;vector<bool>visit(graph.size(),false);vector<int>ret;//记录节点的先继节点已经访问的数目vector<int>pres_visit_num(graph.size(),0);//无先继节点可直接访问for(int i=0;i<graph.size();++i){if(graph[i].pres_num ==0){visit[i]=true;ret.push_back(i);//当前节点的子节点的父节点访问数+1for(auto child:graph[i].childs){++pres_visit_num[child];q.push(child);}}}while(!q.empty()){auto curr=q.front();q.pop();//当前节点未访问 且其先继节点均访问完毕if(visit[curr]==false && pres_visit_num[curr]==graph[curr].pres_num){visit[curr]=true;ret.push_back(curr);for(auto child:graph[curr].childs){if(visit[child]==false){++pres_visit_num[child];q.push(child);}}}       }bool all_visit=true;for(auto i:visit){if(!i) {all_visit=false;ret.clear();break;}}return ret;
}class Solution {public:vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {vector<Node>graph(numCourses);for(auto &pre:prerequisites){graph[pre[0]].pres_num++;graph[pre[1]].childs.push_back(pre[0]);}return BFS(graph);}
};

球球速刷LC--BFS DFS 二轮相关推荐

  1. 球球速刷LC之DP问题 三轮

    目录 经典 三角形最小路径和 网格递推 到达路径数目333 到达路径数目2 最大正方形333 骑士游戏 序列DP 股票系列 只能交易一次333 交易任意次数333 只能交易2次 只能交易K次333 交 ...

  2. Leetcode一起攻克搜索(BFS,DFS,回溯,并查集)

    文章目录 BFS简介 DFS简介 回溯简介 并查集简介 DFS题目 690. 员工的重要性 1.dfs解法: 2.bfs算法 547.朋友圈 dfs解法 200.岛屿数量 dfs解法 417.太平洋大 ...

  3. 动态规划+BFS+DFS+回溯+红黑树+排序+链表+位运算(B站优质学习资源链接,后续会继续更新)

    动态规划 正月点灯笼(UP主) 个人主页 https://space.bilibili.com/24014925/channel/detail?cid=12580 动态规划第一讲 https://ww ...

  4. LeetCode 1034. 边框着色(BFS/DFS)

    文章目录 1. 题目 2. 解题 2.1 BFS 2.2 DFS 1. 题目 给出一个二维整数网格 grid,网格中的每个值表示该位置处的网格块的颜色. 只有当两个网格块的颜色相同,而且在四个方向中任 ...

  5. 7位格雷码计算风向_七哥特刊|从二轮秀到队内得分王 格雷厄姆会新的蜂王吗?...

    乔丹老爷子贵为篮球之神,在球场上的辉煌功绩无需多述,但其选人的眼光与随意开出的垃圾合同,足以证明其并不是个拥有好眼光的的伯乐. 从早前的夸梅-布朗到山猫时期的迈克尔-吉尔克里斯特:从顶薪续约巴图姆最终 ...

  6. Python BFS 提取二值图联通域

    <Python BFS 提取二值图联通域>    2016年实习那会儿在京东搞身份证 OCR,那时候的OCR是基于 CNN 的单字识别的pipeline,所以就需要一些方法来对字符进行切割 ...

  7. SDOI 2018二轮题解(除Day2T1)

    博主诈尸啦 虽然一轮之后就退役了但是二轮还是要去划划水呀~ 然鹅学了不到一个月文化课再回来看OI的东西有一种恍如隔世的感觉,烤前感觉也没啥可复习的,就补一补去年二轮的题吧. 题目思路基本都参考自sha ...

  8. 一台小型发电机与计算机相连,2020春青岛市高考物理二轮45分钟练习:交变电流的产生及描述含答案...

    第 1 页 共 10 页 2020春青岛市高考物理二轮45分钟练习:交变电流的产生及描述含答案 建议用时:45分钟 1.(2019·广西桂林市.贺州市期末联考)一台小型发电机与计算机相连接,计算机能将 ...

  9. 【八数码问题】基于状态空间法的知识表示与状态搜索:无信息搜索(BFS/DFS) 启发式搜索(A*)

    前言 一.问题引入 二.状态空间法 1. 知识及其表示 2. 状态空间法定义 3. 问题求解 三.基于状态空间搜索法解决八数码问题 1. 八数码问题的知识表示 2. 状态空间图搜索 1. 无信息搜索 ...

最新文章

  1. gradle 指定springcloud 版本_SpringCloud微服务架构开发实战:实现服务注册与发现
  2. quake3使用指南(转载)
  3. BZOJ1030: [JSOI2007]文本生成器
  4. 【LeetCode-SQL每日一练】—— 1179. 重新格式化部门表
  5. Dubbo与SpringCloud的架构与区别
  6. 宽幅FLASH产品展示代码多图带左右显示按钮 - 图
  7. 自定义过滤器和标签,动态显示菜单权限
  8. 走出软件质量困境的指导性思想
  9. 安卓车机没有ADB调试,任意安装第三方软件教程
  10. 基于Spring的医院药品管理系统的设计与实现
  11. 封装React-PDF预览组件--canvas渲染篇
  12. 【时序】DCRNN:结合扩散卷积和GNN的用于交通流量预测的时空预测网络
  13. SA上传吞吐率优化经验总结
  14. 旧苹果短信导入新苹果手机上,iphone短信迁移
  15. ML-czy的小组任务
  16. python黑色背景rbg_PIL图像转换为RGB,保存为纯黑色图像(python)
  17. ChatGPT ,能替代程序员吗?
  18. hexo引用本地图片无法显示
  19. java 联系电话/证件号码脱敏处理
  20. android 9.0谷歌商店,Android 10现可选择Play商店主题模式 附Android 9强制开启深色模式教程...

热门文章

  1. Fisher线性判别 模式识别 例题
  2. java url 图片路径_问个URL图片路径问题
  3. lscpu与cat /proc/cpuinfo获取的CPU信息释义
  4. CF1452 D. Radio Towers(斐波那契数列+概率)
  5. Error: Unknown command: cask
  6. BZOJ4399 魔法少女LJJ【线段树合并】【并查集】
  7. python selenium爬取去哪儿网的酒店信息——详细步骤及代码实现
  8. linux系统启动的第一个进程是,CentOS6开机启动过程详解
  9. JS中事件绑定的方式以及事件监听和事件的委托
  10. 苹果支付php服务端处理,以及双重验证,收据,状态码