二叉树的层序遍历 力扣可以一口气打十个的那种
经过一段时间对数据结构和算法的学习,深深的体会到了代码的魅力,很多人刚开始学数据结构的时候直接就开始死磕到底,往往到最后自己也不知道方向如何。学习数据结构和算法一定要多看代码,多敲代码,多总结代码,把别人的思想借鉴然后逐步按照自己的理解去改,不要一上来就我做不出来该咋办,没有效率。我在这整理了十个广度优先搜索的力扣习题,针对一套代码模板进行代码刨析,希望对大家的学习有帮助!
模板:
/** * 层序遍历 */ class CopyRight { public List<List<Integer>> levelOrder(TreeNode root) { Queue(root);//对Queue方法的引用 return resList; } List<List<Integer>> resList =new ArrayList<List<Integer>>();//创建集合对结果进行保存 void Queue(TreeNode node){ Queue<TreeNode> queue =new LinkedList<>();//定义一个新的队列 queue.offer(node);//将节点值加入到队列中 while(!queue.isEmpty()){ List<Integer> list =new ArrayList<>(); int len = queue.size();//记录队列的长度 while(len > 0){ TreeNode treeNode = queue.poll(); //将队列中的元素抛出,但是要注意记录下每一层的节点数量 ,不然十分容易和下一层的节点数混淆 list.add(treeNode.val);//将拿到的节点值放入集合中 if (treeNode.left != null){ queue.offer(treeNode.left); } if (treeNode.right!= null){ queue.offer(treeNode.left); } } resList.add(list); } } }
102.二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
class Solution { public List<List<Integer>> resList = new ArrayList<List<Integer>>(); public List<List<Integer>> levelOrder(TreeNode root) { Queues(root); return resList; } void Queues(TreeNode node){ if (node == null) return; Queue<TreeNode> que = new LinkedList<TreeNode>(); que.offer(node); while (!que.isEmpty()) { List<Integer> itemList = new ArrayList<Integer>(); int len = que.size(); while (len > 0) { TreeNode tmpNode = que.poll(); itemList.add(tmpNode.val); if (tmpNode.left != null) que.offer(tmpNode.left); if (tmpNode.right != null) que.offer(tmpNode.right); len--; } resList.add(itemList); } } }
107.二叉树的层次遍历 II
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
class Solution { public List<List<Integer>> resList = new ArrayList<List<Integer>>(); public List<List<Integer>> levelOrderBottom(TreeNode root) { Queues(root); return resList; } void Queues(TreeNode node){ if(node == null){ return; } Queue<TreeNode> que = new LinkedList<TreeNode>(); que.offer(node); while(!que.isEmpty()){ List<Integer> list = new ArrayList<>(); int len = que.size(); while(len>0){ TreeNode treeNode = que.poll(); if(treeNode.left !=null){ que.offer(treeNode.left); } if(treeNode.right !=null){ que.offer(treeNode.right); } len --; list.add(treeNode.val); } resList.add(0, list); } } }
199.二叉树的右视图
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
class Solution { public List<Integer> rightSideView(TreeNode root) { List<Integer> result = new ArrayList<>(); if(root == null){return result;} Queue<TreeNode>Queue = new LinkedList<TreeNode>(); Queue.offer(root); while(!Queue.isEmpty()){ int size = Queue.size(); for(int i =0; i < size ;i++){ TreeNode TreeNode = Queue.poll(); if(TreeNode.left != null){ Queue.offer(TreeNode.left); } if(TreeNode.right != null){ Queue.offer(TreeNode.right); } if(i == size -1){ result.add(TreeNode.val); } } } return result; } }
637.二叉树的层平均值
给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。
class Solution { public List<Double> averageOfLevels(TreeNode root) { List<Double> List = new ArrayList<Double>(); if(root == null){ return List; } Queue<TreeNode> Queue = new LinkedList<TreeNode>(); Queue.offer(root); while(!Queue.isEmpty()){ int size = Queue.size(); double sum = 0; for(int i = 0; i <size; i ++){ TreeNode TreeNode = Queue.poll(); sum += TreeNode.val; if(TreeNode.left!=null){ Queue.offer(TreeNode.left); } if(TreeNode.right!=null){ Queue.offer(TreeNode.right); } }List.add(sum/size); } return List; } }
429.N叉树的层序遍历
给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
例如,给定一个 3叉树 :
返回其层序遍历:
[ [1], [3,2,4], [5,6] ]
class Solution { public List<List<Integer>> levelOrder(Node root) { if (root == null) { return new ArrayList<List<Integer>>(); } List<List<Integer>> ans = new ArrayList<List<Integer>>(); Queue<Node> queue = new ArrayDeque<Node>(); queue.offer(root); while (!queue.isEmpty()) { int cnt = queue.size(); List<Integer> level = new ArrayList<Integer>(); for (int i = 0; i < cnt; ++i) { Node cur = queue.poll(); level.add(cur.val); for (Node child : cur.children) {//对children进行for-each 将值保存在队列中 queue.offer(child); } } ans.add(level); } return ans; } }
515.在每个树行中找最大值
您需要在二叉树的每一行中找到最大的值。
思路:遍历每一层,取最大值
class Solution { public List<Integer> largestValues(TreeNode root) { if(root == null){ return Collections.emptyList(); } List<Integer> result = new ArrayList(); Queue<TreeNode> queue = new LinkedList(); queue.offer(root); while(!queue.isEmpty()){ int max = Integer.MIN_VALUE; for(int i = queue.size(); i > 0; i--){ TreeNode node = queue.poll(); max = Math.max(max, node.val);//对节点值和max比较取较大值 if(node.left != null) queue.offer(node.left); if(node.right != null) queue.offer(node.right); } result.add(max); } return result; } }
116.填充每个节点的下一个右侧节点指针
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
1
2
3
4
5
6
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
思路:在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了。
class Solution { public Node connect(Node root) { Queue<Node> tmpQueue = new LinkedList<Node>(); if (root != null) tmpQueue.add(root); while (tmpQueue.size() != 0){ int size = tmpQueue.size(); Node cur = tmpQueue.poll(); if (cur.left != null) tmpQueue.add(cur.left); if (cur.right != null) tmpQueue.add(cur.right); for (int index = 1; index < size; index++){ Node next = tmpQueue.poll(); if (next.left != null) tmpQueue.add(next.left); if (next.right != null) tmpQueue.add(next.right); cur.next = next; cur = next; } } return root; } }
117.填充每个节点的下一个右侧节点指针II
将指针和队列结合的中等题型
class Solution { public Node connect(Node root) { if (root == null) return root; Queue<Node> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { //每一层的数量 int levelCount = queue.size(); //前一个节点 Node pre = null; for (int i = 0; i < levelCount; i++) { //出队 Node node = queue.poll(); //如果pre为空就表示node节点是这一行的第一个, //没有前一个节点指向他,否则就让前一个节点指向他 if (pre != null) { pre.next = node; } //然后再让当前节点成为前一个节点 pre = node; //左右子节点如果不为空就入队 if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } } return root; } }
104.二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
返回它的最大深度 3 。
class Solution { public int maxDepth(TreeNode root) { if(root == null){ return 0 ; } Queue<TreeNode> Queue = new LinkedList<TreeNode>(); Queue.offer(root); int depth = 0 ; while(!Queue.isEmpty()){ int size = Queue.size(); while(size > 0 ){ TreeNode node = Queue.poll(); if(node.left != null){ Queue.offer(node.left); } if(node.right != null){ Queue.offer(node.right); } size -- ; } depth++; } return depth; } }
111.二叉树的最小深度
class Solution { public int minDepth(TreeNode root) { if(root == null){ return 0; } Queue<TreeNode> Queue = new LinkedList<TreeNode>(); Queue.offer(root); int depth = 0; while(!Queue.isEmpty()){ int size = Queue.size(); depth ++; TreeNode cur = null; for(int i =0; i < size; i++){ cur = Queue.poll(); if(cur.right ==null && cur.left == null){ return depth; } if(cur.left != null){ Queue.offer(cur.left); } if(cur.right != null){ Queue.offer(cur.right); } } } return depth; } }
总结
二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列,一起来实现一口气打十个。给生活加点料。