leetcode-dfs总结

一:二分图:颜色分图

 1: leetcode:785 https://leetcode-cn.com/problems/is-graph-bipartite/

          leetcode-dfs总结_第1张图片

        思想:即然要分成两组,二分,即颜色不同,把一天边的两个结点分成A,B两个集合,则考虑用一个颜色(eg:蓝色)赋予当                     前结点,把与它相邻的结点赋予另一颜色(eg:红色),采用dfs,一个个结点dfs,只要遇到即将访问结点与当前点                       颜色相同则,说明冲突,无法二分。

        代码:

       leetcode-dfs总结_第2张图片

 2:leetcode886:https://leetcode-cn.com/problems/possible-bipartition/

leetcode-dfs总结_第3张图片

  代码:leetcode-dfs总结_第4张图片

 

二:判断图是否有环,或者计算连通图的个数

1:leetcode207(用dfs判断是否有环):https://leetcode-cn.com/problems/course-schedule/

leetcode-dfs总结_第5张图片

思想:只要判断是否有环即可,有环则肯定不行。通过一个vectorflag来记录依次访问,没有访问的赋值0,对已经确定(已经确定,就是从这个结点出发,沿着与之相关的有向边出发,不会出现环)了的结点赋值1,正在访问过程中的结点(就是某个的结点的路径,暂时还不能确定该路径是否会形成环)赋值-1,每个结点的有向边,对当前结点dfs。

leetcode-dfs总结_第6张图片

       

2:210(用dfs判断是否有环,同207): https://leetcode-cn.com/problems/course-schedule-ii/

leetcode-dfs总结_第7张图片

思想:如207,只是需要记录路径

代码:

leetcode-dfs总结_第8张图片

3:802(用拓扑排序来判断是否有环) https://leetcode-cn.com/problems/find-eventual-safe-states/

leetcode-dfs总结_第9张图片

思想:就是判断从某个结点出发,如果不存在环,则加入结果集,此时不能再用207,210,那样的方法,会超时,这里选择拓扑排序,采用逆向的,也就是先将出度为0的结点加入结果集(出度为0,肯定是结果集的一员),再计算每个结点的出度output[i],再用input[i][j]来存储结点j->i的有向边,从结果集里选择出度为0的结点,比如i=1,结点1,去input[1][j]里找到,所有指向结点1的有向边,每遍历一条,就将结点j的出度,output[j]--,同时检出output[j]是否等与0,若output[j] ==0,则加入结果集。

代码:leetcode-dfs总结_第10张图片

4:leetcode323(用dfs来数无向图连通分量个数)

https://leetcode-cn.com/problems/number-of-connected-components-in-an-undirected-graph/

思路:先构建无向图的邻接矩阵,再依此dfs,调用完一次dfs,无向图连通图的数量++,

代码:

leetcode-dfs总结_第11张图片

5:leetcode547(用dfs判断无向连通图的个数,同323,很相似)

https://leetcode-cn.com/problems/friend-circles/

leetcode-dfs总结_第12张图片

代码:

leetcode-dfs总结_第13张图片

6:leetcode947(用并查集数无向连通图的个数)

https://leetcode-cn.com/problems/most-stones-removed-with-same-row-or-column/

leetcode-dfs总结_第14张图片

思路:将同一行的列,或行,就可看成无向连通图的边,通过不断更新根节点parent[i] = j,从而达到连起来的目的,记住并查集的模板,即建立一个class,DSU(){在parent[i] = i,(赋初值)},int find(){找根节点},void merge(int a,int b){更新根节点};

代码:

leetcode-dfs总结_第15张图片

7:leetcode1319(同947,并查集解决无向图连通分量的个数)

https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected/

leetcode-dfs总结_第16张图片

思路:首先要知道,要想整体连通,则变数 >= 结点数-1,然后就是计算连通分量个数,

代码:leetcode-dfs总结_第17张图片

8:leetcode959(不同947和1319,仅仅是为了熟悉,记住并查集的模板才写在这,为了对比下,与dfs相似)

https://leetcode-cn.com/problems/regions-cut-by-slashes/

leetcode-dfs总结_第18张图片

思想:把每个小正方形,分成上下左右四个更小的正方形

类似这样:leetcode-dfs总结_第19张图片,初始结果为n*n*4,然后进行一小个一小个合并,每合并一次,结果--,

代码:

leetcode-dfs总结_第20张图片

 

三:字符串型的dfs

1:leetcode332(字符串转化为数字dfs)

https://leetcode-cn.com/problems/reconstruct-itinerary/

leetcode-dfs总结_第21张图片

思想:其实就是一个连通图,已知起点,求按字母顺序的一个路径。将各城市转化为数字对应,建立邻接表,一遍dfs记录路径。

代码:

leetcode-dfs总结_第22张图片

2:leetcode721

https://leetcode-cn.com/problems/accounts-merge/

题目:

leetcode-dfs总结_第23张图片

思想:以email来建立无向图,并建立一个email 到 name的映射,每一个Name,进行一次dfs,将与其相关的email的边连通起来,加入对应的结果集。

 

代码:

leetcode-dfs总结_第24张图片

 

四:岛屿面积,数量,形状(上下左右)

1:leetcode200(岛屿数量,就是计算连通分量个数,只不过在坐标上)

https://leetcode-cn.com/problems/number-of-islands/

leetcode-dfs总结_第25张图片

思想:常规dfs,遇到1就继续上下左右一起扩张。

代码:leetcode-dfs总结_第26张图片

2:leetcode694(不同形状的岛屿数量)

https://leetcode-cn.com/problems/number-of-distinct-islands/

题目:

leetcode-dfs总结_第27张图片

思想:其实与200题差不多,主要是如何理解形状,这里我们采用一个简单的方法,通过其所走的轨迹,来判断形状是否相同用set来存储,这样可以自动去重复的轨迹(也就是重复的轨迹并不会保存)。重点理解(i-r)*row+j-c。

代码:

leetcode-dfs总结_第28张图片

3:leetcode695(岛屿最大面积,其实同694不同形状的岛屿数量)

https://leetcode-cn.com/problems/max-area-of-island/

题目:

leetcode-dfs总结_第29张图片

思想:只要求最大面积,则与694的不同形状,就很相似,只用不断更新最大路径的值即可。

代码:

leetcode-dfs总结_第30张图片

五:迷宫,上下左右遍历

1:leetcode490

https://leetcode-cn.com/problems/the-maze/

leetcode-dfs总结_第31张图片

思想:上下左右走,只不过要先用while来使其走到某个节点。

代码:

leetcode-dfs总结_第32张图片

2:leetcode505(与490相似,只不过要求最短的路径)

https://leetcode-cn.com/problems/the-maze-ii/

题目:

leetcode-dfs总结_第33张图片

思路:有点难,用BFS做,

leetcode-dfs总结_第34张图片

3:leetcode417(遍历方式改为从四周边界遍历)

https://leetcode-cn.com/problems/pacific-atlantic-water-flow/

题目:

leetcode-dfs总结_第35张图片

思路:采用逆流的方法,因为能留到海洋,则当前位置的高度>=下一结点的高度,反过来,逆流,从海洋出发往里留,就是pre [i][j]<= now[i][j];

代码:

leetcode-dfs总结_第36张图片

4:leetcode1020(依然从边界开始遍历)

https://leetcode-cn.com/problems/number-of-enclaves/

题目:

leetcode-dfs总结_第37张图片

思路:要想算出不能走到边界上,那反过来想,就可以先算出来,可以从边界往里走,更改可以走到的值,最后再记录那些没有被更改的值的个数。

代码:

leetcode-dfs总结_第38张图片

六:用dp解决的dfs

1:leetcode542

https://leetcode-cn.com/problems/01-matrix/

题目:

leetcode-dfs总结_第39张图片

思路:

对于一个节点来说,它到 0 的距离可以通过邻居的最近距离计算,在这种情况下最近距离是邻居的距离 + 1。因此,这就让我们想到了动态规划!对于每个 1,到 0 的最短路径可能从任意方向。所以我们需要检查所有 4 个方向。在从上到下的迭代中,我们需要检查左边和上方的最短路径;我们还需要另一个从下往上的循环,检查右边和下方的方向。

从上至下、从左至右迭代整个矩阵

从下到上、从右至左迭代整个矩阵

 

代码:

leetcode-dfs总结_第40张图片

2:leetcode576(dp有点难)

https://leetcode-cn.com/problems/out-of-boundary-paths/

题目:

leetcode-dfs总结_第41张图片

思想:

代码:

leetcode-dfs总结_第42张图片

3:leetcode 743(在dfs的过程中,相当于加了个限制条件)

https://leetcode-cn.com/problems/network-delay-time/

题目:

leetcode-dfs总结_第43张图片

思想:有点像计算结点间的距离,要求最大距离,因此将每个结点的的dp[i] 计算,最后选取最大的,因为消息要传到每个人。

代码:

leetcode-dfs总结_第44张图片

4:leetcode851()

https://leetcode-cn.com/problems/loud-and-rich/

题目:

leetcode-dfs总结_第45张图片

思想:记忆化搜索,通过这种,已经确定了的状态来更快搜索。

代码:

leetcode-dfs总结_第46张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(leetcode-dfs总结)