leetcode之DFS+BFS+DSU刷题总结2

1-对称二叉树
题目链接:题目链接戳这里!!!

思路1:迭代法
一棵二叉树,左右子树分别进队,如果左右子树都为空,则结束遍历,如果左右子树仅一个为空,或左右子树根节点不同,则返回false,否则 ,按照左节点的左子树,右节点的右子树,左节点的右子树,右节点的左子树顺序入队。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean isSymmetric(TreeNode root) {if(root==null){return true ;}Queue<TreeNode> queue = new LinkedList<>() ;queue.add(root.left) ;queue.add(root.right) ;while(!queue.isEmpty()){TreeNode node1 = queue.poll() ;TreeNode node2 = queue.poll() ;if(node1 == null && node2 == null){continue ;}if(node1==null || node2==null || node1.val != node2.val){return false ;}queue.add(node1.left) ;queue.add(node2.right) ;queue.add(node1.right) ;queue.add(node2.left) ;}return true ;}
}


思路2:递归法
和思路1方法一样,不过没有用到队列,直接递归比较。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean isSymmetric(TreeNode root) {if(root==null){return true ;}return f(root.left, root.right) ;}public boolean f(TreeNode node1, TreeNode node2){if(node1==null && node2==null){return true ;}if(node1==null || node2==null || node1.val != node2.val){return false ;}return f(node1.left,node2.right) && f(node1.right,node2.left) ;}
}


2-二叉树的层次遍历
题目链接:题目链接戳这里!!!

思路1:bfs
借助队列,首先让根节点入队,只要队不空,计算队列的大小,每次将每一层的根节点放入集合,同时将左右子树入队。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {if(root==null){return new ArrayList<>() ;}List<List<Integer>> ans = new ArrayList<>() ;Queue<TreeNode> queue = new LinkedList<>() ;queue.add(root) ;while(!queue.isEmpty()){int size = queue.size() ;List<Integer> list = new ArrayList<>() ;while(size>0){TreeNode node = queue.poll() ;list.add(node.val) ;if(node.left != null){queue.add(node.left) ;}if(node.right != null){queue.add(node.right) ;}size -- ;}ans.add(list) ;}return ans ;}
}


3-二叉树的锯齿形遍历
题目链接:题目链接戳这里!!!

思路:bfs+翻转
和层次遍历思路一样,只不过对于偶数层的元素,存入集合后,将奇数元素翻转即可。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {if(root==null){return new ArrayList<>() ;}List<List<Integer>> ans = new ArrayList<>() ;Queue<TreeNode> queue = new LinkedList<>() ;queue.add(root) ;while(!queue.isEmpty()){int size = queue.size() ;boolean level = true ;List<Integer> list = new ArrayList<>() ;while(size>0){TreeNode node = queue.poll() ;list.add(node.val) ;if(node.left != null){queue.add(node.left) ;}if(node.right != null){queue.add(node.right) ;} size -- ;}if(ans.size()%2!=0){Collections.reverse(list) ;}ans.add(list) ;}return ans ;}
}


4-二叉树的最大深度
题目链接:题目链接戳这里!!!

思路1:递归法

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int maxDepth(TreeNode root) {if(root==null){return 0 ;}return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1 ;}
}


思路2:bfs
使用队列进行层次遍历,没遍历一层二叉树的高度height加1.

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int maxDepth(TreeNode root) {if(root==null){return 0 ;}int height = 0 ;Queue<TreeNode>  queue = new LinkedList<>() ;queue.add(root) ;while(!queue.isEmpty()){int size = queue.size();height ++ ;for(int i=0; i<size; i++){TreeNode node = queue.poll() ;if(node.left != null){queue.add(node.left) ;}if(node.right != null){queue.add(node.right) ;}}}return height ;}
}


5-二叉树的层序遍历II
题目链接:题目链接戳这里!!!

思路:bfs
bfs进行层次遍历,对每一层的遍历结果插入到结果集合的头部。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<List<Integer>> levelOrderBottom(TreeNode root) {if(root==null){return new ArrayList<>() ;}LinkedList<List<Integer>> ans = new LinkedList<>() ;Queue<TreeNode> queue = new LinkedList<>() ;queue.add(root) ;while(!queue.isEmpty()){int size = queue.size() ;List<Integer> temp = new LinkedList<>() ;for(int i=0; i<size; i++){TreeNode node = queue.poll() ;temp.add(node.val) ;if(node.left != null){queue.add(node.left) ;}if(node.right != null){queue.add(node.right) ;}}ans.addFirst(temp) ; }return ans ;}
}

6-二叉树的最小深度
题目链接:题目链接戳这里!!!

思路1:dfs法

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int minDepth(TreeNode root) {if(root==null){return 0 ;}if(root.left==null && root.right != null){ //根节点的左子树为空,只需考虑右子树return minDepth(root.right) + 1 ;}if(root.right==null && root.left!=null){//根节点的右子树为空,只需考虑左子树return minDepth(root.left) + 1 ;}return Math.min(minDepth(root.left),minDepth(root.right)) + 1  ;}
}


思路2:bfs
将根节点进队,如果队不空,依次层次遍历,如果某一层左右子树都为空,则结束遍历,否则继续遍历。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int minDepth(TreeNode root) {if(root==null){return 0 ; }Queue<TreeNode> queue = new LinkedList<>() ;queue.add(root) ;int height = 0 ;while(!queue.isEmpty()){int size = queue.size() ;height ++ ;for(int i=0; i<size; i++){TreeNode node = queue.poll() ;if(node.left==null && node.right==null){return height ;}if(node.left!=null){queue.add(node.left) ;}if(node.right!=null){queue.add(node.right) ;}}}return height ;}
}


7-最小高度树
题目链接:题目链接戳这里!!!

思路:拓朴排序+bfs

我们从边缘开始,先找到所有出度为1的节点,然后把所有出度为1的节点进队列,然后不断地bfs,最后找到的就是两边同时向中间靠近的节点,那么这个中间节点就相当于把整个距离二分了,那么它当然就是到两边距离最小的点啦,也就是到其他叶子节点最近的节点了。

class Solution {public List<Integer> findMinHeightTrees(int n, int[][] edges) {List<Integer> ans = new ArrayList<>();Queue<Integer> queue = new LinkedList<>() ;List<List<Integer>> adj = new ArrayList<>() ;if(n==1){ans.add(0) ;return ans ;}int [] degree = new int [n] ; //记录出度for(int i=0; i<n; i++){adj.add(new ArrayList<>()) ;}for(int []edge : edges){degree[edge[0]] ++ ;degree[edge[1]] ++ ;adj.get(edge[0]).add(edge[1]) ;adj.get(edge[1]).add(edge[0]) ;}for(int i=0; i<n; i++){if(degree[i]==1){queue.add(i) ;}}while(!queue.isEmpty()){int size = queue.size() ;ans = new ArrayList<>() ;for(int i=0; i<size; i++){int x = queue.poll() ;ans.add(x) ;for(int y : adj.get(x)){degree[y] -- ;if(degree[y]==1){queue.add(y) ;}}}}return ans ;}
}


8-翻转二叉树
题目链接:题目链接戳这里!!!

思路:递归翻转左右子树即可。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode invertTree(TreeNode root) {if(root==null){return null ;}TreeNode left = invertTree(root.left) ;TreeNode right = invertTree(root.right) ;root.left = right ;root.right = left ;return root ;}
}


9-二维网格图中探测环
题目链接:题目链接戳这里!!!

思路:dfs

使用dfs来检测是否有环
有环的条件就是在搜索的过程中搜索到 该次 dfs已经访问过的坐标。
定义一个二维数组记录以及访问过的坐标。
考虑根据在搜索的过程中添加上一层搜索过来的方向,不搜索该方向的反方向。
在这种情况下如果找到已经访问过的节点就说明有环,有环就直接返回。

class Solution {boolean flag = false ;boolean [][] vis;public boolean containsCycle(char[][] grid) {//dfs搜索,不能一步移动到上一次移动得地方,如果最终返回之前访问过的地方,则有环int m = grid.length ;int n = grid[0].length ;vis = new boolean[m][n] ;for(int i=0; i<m; i++){for(int j=0; j<n; j++){if(!vis[i][j]){dfs(grid,i,j,grid[i][j],'L') ;if(flag){return true ;}}}}return false ;}public void dfs(char [][] grid, int x, int y, char target, char c){if(x<0 || y<0 || x>=grid.length || y>=grid[0].length || grid[x][y]!=target){return ;}if(vis[x][y]){flag = true ;return ;}vis[x][y] = true ;if(c!='L'){dfs(grid,x,y-1,target,'R') ;}if(c!='R'){dfs(grid,x,y+1,target,'L') ;}if(c!='U'){dfs(grid,x-1,y,target,'D') ;}if(c!='D'){dfs(grid,x+1,y,target,'U') ;}}
}


10-节点间通路
题目链接:题目链接戳这里!!!

思路1:邻接表+dfs

将二维数组改变成邻接表,即有向无环图,从起点开始对图进行搜索,如果搜索到target点,则说明从start到target有通路。

class Solution {public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {//dfsList<List<Integer>> edges = new ArrayList<>() ;for(int i=0; i<n; i++){edges.add(new ArrayList<>()) ;}for(int [] g : graph){edges.get(g[0]).add(g[1]) ;}return dfs(edges,start,target) ;}public boolean dfs(List<List<Integer>> edges, int start, int target){if(start==target){return true ;}for(int neighbors : edges.get(start)){if(dfs(edges,neighbors,target)){return true ;}}return false ;}
}


思路2:邻接表+bfs
根据graph数组建立邻接表,对邻接表进行广度优先遍历,如果找到target,则返回true。

class Solution {public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {//bfsList<List<Integer>> edges = new ArrayList<>() ;for(int i=0; i<n; i++){edges.add(new ArrayList<>()) ;}for(int [] g : graph){edges.get(g[0]).add(g[1]) ;}Queue<Integer> queue = new LinkedList<>() ;queue.add(start) ;while(!queue.isEmpty()){int x = queue.poll() ;if(x==target){return true ;}for(int neighbors : edges.get(x)){if(neighbors==target){return true ;}queue.add(neighbors) ;}}return false ;}
}


11-二分图
题目链接:题目链接戳这里!!!

思路1:dfs+染色法
我们使用图搜索算法从各个连通域的任一顶点开始遍历整个连通域,遍历的过程中用两种不同的颜色对顶点进行染色,相邻顶点染成相反的颜色。这个过程中倘若发现相邻的顶点被染成了相同的颜色,说明它不是二分图;反之,如果所有的连通域都染色成功,说明它是二分图。

class Solution {int [] vis ;public boolean isBipartite(int[][] graph) {//dfs+染色法vis = new int [graph.length] ;for(int i=0; i<graph.length; i++){if(vis[i]==0 && !dfs(graph,i,vis,1)){return false ;}}return true ;}public boolean dfs(int [][] graph, int x, int [] vis, int color){if(vis[x] != 0){return vis[x]==color ;}vis[x] = color ;for(int y : graph[x]){if(!dfs(graph,y,vis,-color)){return false ;}}return true ;}
}


思路2:bfs+染色法

class Solution {int [] vis ;public boolean isBipartite(int[][] graph) {//dfs+染色法vis = new int [graph.length] ;Queue<Integer> queue = new LinkedList<>() ;for(int i=0; i<graph.length; i++){if(vis[i] != 0){continue ;}queue.add(i) ;vis[i] = 1 ;while(!queue.isEmpty()){int x = queue.poll() ;for(int y : graph[x]){if(vis[x]==vis[y]){return false ;}if(vis[y]==0){vis[y] = - vis[x] ;queue.add(y) ;}}}}return true ;}
}


12-分割回文子字符串
题目链接:题目链接戳这里!!!

思路:记忆化dfs+回溯
假设我们当前搜索到字符串的第 ii个字符,且 s[0…i−1] 位置的所有字符已经被分割成若干个回文串,并且分割结果被放入了答案数组temp 中,那么我们就需要枚举下一个回文串的右边界 j,使得s[i…j] 是一个回文串。

因此,我们可以从 i开始,从小到大依次枚举 j。对于当前枚举的 j值,我们使用双指针的方法判断s[i…j] 是否为回文串:如果 s[i…j] 是回文串,那么就将其加入答案数组 temp 中,并以 j+1 作为新的 i 进行下一层搜索,并在未来的回溯时将s[i…j] 从 temp中移除。

如果我们已经搜索完了字符串的最后一个字符,那么就找到了一种满足要求的分割方法。

class Solution {String [][] ans ;List<List<String>> res = new ArrayList<>() ;List<String> temp = new ArrayList<>() ;int [][] f ;public String[][] partition(String s) {//回溯+记忆化搜索f = new int [s.length()][s.length()] ;dfs(0,s) ;ans = new String[res.size()][] ;for(int i=0; i<res.size(); i++){ans[i] = new String[res.get(i).size()] ;for(int j=0; j<res.get(i).size(); j++){ans[i][j] = res.get(i).get(j) ;}}return ans ;}public void dfs(int i, String s){if(i==s.length()){res.add(new ArrayList<>(temp)) ;return ;}for(int j=i; j<s.length(); j++){if(isPalindrome(s,i,j)==1){temp.add(s.substring(i,j+1)) ;dfs(j+1,s) ;temp.remove(temp.size()-1) ;}}}public int isPalindrome(String s, int i, int j){if(f[i][j] != 0){return f[i][j] ;}if(i>=j){f[i][j] = 1;}else if(s.charAt(i) == s.charAt(j)){f[i][j] = isPalindrome(s,i+1,j-1) ;}else{f[i][j] = -1;}return f[i][j] ;}
}


13-二叉树的深度
题目链接:题目链接戳这里!!!

思路1:直接递归

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public int maxDepth(TreeNode root) {if(root==null){return 0 ;}return Math.max(maxDepth(root.left),maxDepth(root.right))+1 ;}
}


思路2:bfs层次遍历,并记录树的深度

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public int maxDepth(TreeNode root) {if(root==null){return 0 ;}Queue<TreeNode> queue = new LinkedList<>() ;int depth = 0 ;queue.add(root) ;while(!queue.isEmpty()){int size = queue.size() ;for(int i=0; i<size; i++){TreeNode node = queue.poll() ;if(node.left!=null){queue.add(node.left) ;}if(node.right!=null){queue.add(node.right) ;}}depth ++ ;}return depth ;}
}


14-统计二叉树中好节点的数目
题目链接:题目链接戳这里!!!
思路:dfs搜索左右子树,遇到比当前值大的,ans就加1,同时更新最大值。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {int ans = 0 ;public int goodNodes(TreeNode root) {dfs(root,Integer.MIN_VALUE) ;return ans ;}public void dfs(TreeNode root, int max){if(root==null){return ;}if(root.val>=max){ans ++ ;}dfs(root.left,Math.max(max,root.val)) ;dfs(root.right,Math.max(max,root.val)) ;}
}


15-左叶子之和
题目链接:题目 链接戳这里!!!

思路:搜索左右子树,如果当前节点的左子树不空,且左子树的左右子树为空,则当前节点为左叶子节点,累加起来。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {int ans = 0 ;public int sumOfLeftLeaves(TreeNode root) {dfs(root) ;return ans ;}public void dfs(TreeNode root){if(root==null){return  ;}if(root.left != null && root.left.left==null && root.left.right==null){ans += root.left.val ;}dfs(root.left) ;dfs(root.right) ;}
}


**

有你相伴,星河滚烫,奋斗吧,少年!!!

**

leetcode之DFS+BFS+DSU刷题总结2相关推荐

  1. LeetCode《算法入门》刷题笔记(31 题全)

    LeetCode<算法入门>刷题笔记(31 题全) 二分查找 1. 二分查找 _解法1:二分搜索(迭代) 解法2:二分搜索(递归) 2. 第一个错误的版本 _解法1:二分 3. 搜索插入位 ...

  2. 力扣 (LeetCode)-对称二叉树,树|刷题打卡

    Github来源:力扣 (LeetCode)|刷题打卡 | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者 [已开启]任务一:刷题打卡 * 10 篇 哪吒人生信条:如果你所学的东西 处于喜欢 ...

  3. Leetcode题目分类指南(单独刷题或学习算法书籍配合使用)

    Leetcode题目分类指南 笔者在学习<算法导论>同时,希望能够配合Leetcode的题目进行分类模块化练习,该分类为笔者自己根据做题学习经验,结合<算法导论>的内容,给出L ...

  4. LeetCode LCP 12. 小张刷题计划(二分查找)

    1. 题目 为了提高自己的代码能力,小张制定了 LeetCode 刷题计划,他选中了 LeetCode 题库中的 n 道题,编号从 0 到 n-1,并计划在 m 天内按照题目编号顺序刷完所有的题目(注 ...

  5. vscode中配置LeetCode插件的教程(愉快刷题)

    转载于脚本之家,原链接为https://www.jb51.net/article/183720.htm 大家好,今早在B站看到up主的vscode里藏了leetcode插件,这才知道原来还有这款神器. ...

  6. LeetCode(力扣) 刷题注意事项 持续更新 ~ ~

    文章目录 刷题无止境,那就让自己快乐一点 刷哪的题 抱前辈大腿 没有思路的题目 提交前检查代码 提交后 可以做的更好 在哪儿看题解 不要试图从题解的代码中理解思路 LeetCode的使用技巧 一次可以 ...

  7. leetcode和牛客网刷题

    在上学时学过<数据结构和算法>这门课,当时学习了数组.链表.哈希表.二叉树.图等数据结构,还有排序算法.二分查找.最短路径算法.关键路径等,当时记得还有ACM比赛,还有那部很烧脑筋的< ...

  8. DFS + BFS + 洛谷题

    DFS 经典的迷宫问题( 回溯 问题 ) 在起点处有四个方向,上下左右, 走到终点之后,要再返回,看有没有其他更短的路径. 回溯过程,退回之后,要标记该点的值为没有访问过. 直到找到最短的路径. 左右 ...

  9. 2018年LeetCode高频算法面试题刷题笔记——只出现一次的数字(开始之前)

    1.解答前的碎碎念: 这个系列是写给找工作前的我看的,毕竟作为一个记性很差的人,可能过一段时间又忘了怎么写了...然后作为开胃菜的第一题就没有思路,真的是让人非常有挫败感了... 2.问题描述: 给定 ...

最新文章

  1. 小脚本,统计一个目录下满足特定条件文件的代码行数
  2. React Native获取手机的各种高度
  3. [BZOJ2599]Race
  4. 【传智播客】Javaweb程序设计任务教程 黑马程序员 第六章 课后答案
  5. R开发(part9)--文件系统管理
  6. 2022,前端工具链十年盘点
  7. 浅析神经网络为什么能够无限逼近任意连续函数
  8. 超级终端设置-基本配置(华为)
  9. 24.QTreeWidget的用法
  10. 下拉推广系统立择火星推荐_【电商干货】拼多多搜索推广 如何选对致命关键词 ?...
  11. TS文件合并,这里提供了一点小思路。
  12. 计算机几何 - 如何判断一个多边形是凸多边形还是凹多边形
  13. 服务器 ssd虚拟内存,ssd虚拟内存设多大
  14. BERT简介及中文分类
  15. python123 第四次作业_第四次作业
  16. 如何查看Mysql是否已经安装
  17. mysql嵌套查询效率低,连接查询代替嵌套查询提高select效率
  18. 四川麻将出现天胡与地胡的概率
  19. 使用echars绘制股票图
  20. 游戏外挂传播后门病毒 欺骗用户“放心使用尽情奔放”

热门文章

  1. 联想Fn+Q重装系统修复,及LegionPowerPlan下载
  2. 最小互质数 (H题)
  3. 超市老板利用人性做营销,锁定大量客户,这一招你也可以用!
  4. 已知A点经纬度坐标,方位角角度,距离,求B点经纬度
  5. 如何设计云存储服务端数据存储加密机制
  6. 魔兽世界编程宝典读书笔记(1)
  7. ios、android 系统字体说明
  8. Hive collect_set与collect_list
  9. 微信小程序开发 开启
  10. Js之跳出循环(for/forEach)