基础算法,二叉树的层序遍历!

Posted 珑心可雕文

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础算法,二叉树的层序遍历!相关的知识,希望对你有一定的参考价值。

        层次遍历:用于一层一层地访问二叉树中的所有结点。其过程如下:

若二叉树非空(假设其高度为h),则:

(1)访问根节点(第一层);

(2)从左到右访问第二层的所有结点;

(3)从左到右访问第三层的所有结点,······,第h层的所有结点。

       对于层次遍历,先访问结点的左右孩子也要先访问,这样与队列的特征相吻合,因此层次遍历算法可采用一个队列来实现。

       层次遍历的具体过程是先将根结点进队,在队列不为空的时候循环,从队列中出列一个结点node,访问它;若它有左孩子结点,将左孩子结点进队;若它有右孩子结点,将右孩子结点进队。如此操作,直到队列为空为止。


leetcode102 二叉树的层序遍历

https://leetcode-cn.com/problems/binary-tree-level-order-traversal/

1.BFS,即使用队列的解法如下:

 public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> resList = new LinkedList<>(); if (root == null) return resList; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(); List<Integer> list = new LinkedList<>(); for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); list.add(node.val); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } resList.add(list); } return resList;  }

2.此外也可使用DFS,此解法不是本文重点,递归解法如下:

 public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> resList = new LinkedList<>(); if (root == null) return resList; dfs(root, 1, resList); return resList; }
public void dfs(TreeNode root, int len, List<List<Integer>> resList) { if (len > resList.size()) { List<Integer> list = new LinkedList<>(); list.add(root.val); resList.add(list); } else { resList.get(len - 1).add(root.val); } if (root.left != null) { dfs(root.left, len + 1, resList); } if (root.right != null) { dfs(root.right, len + 1, resList); } }

学会层次遍历的非递归解法,我们可以轻松解决如下问题,这里列举10道

1.leetcode104 二叉树的最大深度

https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

    public int maxDepth(TreeNode root) { if (root == null) return 0; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int res = 0; while (!queue.isEmpty()) { int num = queue.size(); for (int i = 0; i < num; i++) { TreeNode node = queue.poll(); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } res++; } return res;    }

2.leetcode111 二叉树的最小深度

https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/

 public int minDepth(TreeNode root) { if (root == null) return 0; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int res = 0; while (!queue.isEmpty()) { int size = queue.size(); res++; for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); if (node.left == null && node.right == null) { return res; } if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } } return res; }

3.leetcode100 相同的树

https://leetcode-cn.com/problems/same-tree/

 public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) return true; if (p == null) return false; if (q == null) return false; Queue<TreeNode> pQueue = new LinkedList<>(); Queue<TreeNode> qQueue = new LinkedList<>(); pQueue.offer(p); qQueue.offer(q); while (!pQueue.isEmpty() && !qQueue.isEmpty()) { TreeNode pNode = pQueue.poll(); TreeNode qNode = qQueue.poll(); if (pNode.val != qNode.val) { return false; } if (pNode.left != null && qNode.left != null) { pQueue.offer(pNode.left); qQueue.offer(qNode.left); } else if (pNode.left != null || qNode.left != null) { return false; } if (pNode.right != null && qNode.right != null) { pQueue.offer(pNode.right); qQueue.offer(qNode.right); } else if (pNode.right != null || qNode.right != null) { return false; } } return pQueue.isEmpty() && qQueue.isEmpty(); }

4.leetcode101 对称二叉树

https://leetcode-cn.com/problems/symmetric-tree

 public boolean isSymmetric(TreeNode root) { if (root == null) return false; return isSym(root.left, root.right); }
public boolean isSym(TreeNode rootA, TreeNode rootB){ if (rootA == null && rootB == null) return true; if (rootA == null) return false; if (rootB == null) return false; Queue<TreeNode> queueA = new LinkedList<>(); Queue<TreeNode> queueB = new LinkedList<>(); queueA.offer(rootA); queueB.offer(rootB); while (!queueA.isEmpty() && !queueB.isEmpty()) { TreeNode nodeA = queueA.poll(); TreeNode nodeB = queueB.poll(); if (nodeA.val != nodeB.val) { return false; } if (nodeA.left != null && nodeB.right != null) { queueA.offer(nodeA.left); queueB.offer(nodeB.right); } else if (nodeA.left != null || nodeB.right != null) { return false; } if (nodeA.right != null && nodeB.left != null) { queueA.offer(nodeA.right); queueB.offer(nodeB.left); } else if (nodeA.right != null || nodeB.left != null) { return false; } } return queueA.isEmpty() && queueB.isEmpty(); }

4.leetcode226 翻转二叉树

https://leetcode-cn.com/problems/invert-binary-tree/

    public TreeNode invertTree(TreeNode root) { if (root == null) return null; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); TreeNode temp = node.left; node.left = node.right; node.right = temp; if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } return root; }

5.leetcode103 二叉树的锯齿形层序遍历

https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/

    public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> resList = new LinkedList<>(); if (root == null) return resList; Deque<TreeNode> deque = new LinkedList<>(); deque.add(root); boolean flag = true; while (!deque.isEmpty()) { int size = deque.size(); List<Integer> list = new LinkedList<>(); for (int i = 0; i < size; i++) { TreeNode node = deque.poll(); if (flag) { list.add(node.val); } else { list.add(0, node.val); } if (node.left != null) { deque.offer(node.left); } if (node.right != null) { deque.offer(node.right); } } flag = !flag; resList.add(list); } return resList; }

6.leetcode112 路径总和

https://leetcode-cn.com/problems/path-sum/

    public boolean hasPathSum(TreeNode root, int targetSum) { if (root == null) return false; Queue<TreeNode> queue = new LinkedList<>(); Queue<Integer> tarQueue = new LinkedList<>(); queue.offer(root); tarQueue.offer(targetSum - root.val); while (!queue.isEmpty()) { TreeNode node = queue.poll(); int target = tarQueue.poll(); if (node.left == null && node.right == null && target == 0) { return true; } if (node.left != null) { queue.offer(node.left); tarQueue.offer(target - node.left.val); } if (node.right != null) { queue.offer(node.right); tarQueue.offer(target - node.right.val); } } return false; }

7.leetcode199 二叉树的右视图

https://leetcode-cn.com/problems/binary-tree-right-side-view/

 public List<Integer> rightSideView(TreeNode root) { List<Integer> list = new LinkedList(); if (root == null) return list; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); if (i == size - 1) { list.add(node.val); } if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } } return list; }

8.leetcode107 二叉树的层序遍历2

https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/

 public List<List<Integer>> levelOrderBottom(TreeNode root) { List<List<Integer>> resList = new LinkedList<>(); if (root == null) return resList; Queue<TreeNode> queue = new LinkedList<>();        queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(); List<Integer> list = new LinkedList<>(); for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); list.add(node.val); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } resList.add(0, list); } return resList; }

9.leetcode129 求根到叶子节点数字之和

https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/

    public int sumNumbers(TreeNode root) { if (root == null) return 0; Queue<TreeNode> queueA = new LinkedList<>(); Queue<Integer> queueB = new LinkedList<>(); queueA.offer(root); queueB.offer(root.val); int res = 0; while (!queueA.isEmpty()) { TreeNode node = queueA.poll(); int value = queueB.poll(); if (node.left == null && node.right == null) { res += value; continue; } if (node.left != null) { queueA.offer(node.left); queueB.offer(value * 10 + node.left.val); } if (node.right != null) { queueA.offer(node.right); queueB.offer(value * 10 + node.right.val); } } return res; }

10.leetcode637 二叉树的层平均值

https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/

 public List<Double> averageOfLevels(TreeNode root) { List<Double> list = new LinkedList<>(); Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(); double sum = 0; for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); sum += node.val; if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } list.add(sum / size); } return list; }


万变不离其宗,会了一种解法,一类问题都将迎刃而解!

       

       写在最后,一点与其他的事。

       姐姐离职了,走了,往后无论还是生活还是工作,大概都不会再有交集了吧。其实我的心是很痛的,但我还是会装作若无其事,这是一个男人该有的姿态。早在18岁的时候,我就觉得自己理解了一句话,爱了,让她自由,不爱,让爱自由。如今我22岁,四年过去了,等到自己去经历这句话的时候,我发现要完完全全地做到这句话真的是太难太难了,心碎的滋味真的很难受。

       结束了,一切没有变得更好或者更坏,只是回到了它本来的样子。那些所经历的或许终将随着时间的流逝而逐渐变淡,姐姐的容颜也会逐渐地我的脑海里变得模糊。多年之后再回首此事,又会是怎样一番滋味呢?


       不管你信不信,人确实是在经历了一些事之后,就悄悄换了一种性格。因为,我就是其中一个,仅一夜之间,我的心就判若两人。我站在人生阅历的风口,吹掉了一生纯真。以前我一杯可乐就能开心好久,如今要喝十瓶啤酒,是成长还是堕落,傻傻分不清楚,有很多人叫我戒烟,却没人问过我,为什么抽烟,你知道我在说什么吗。现在翻翻以前的说说,好像在读另一个自己,不知从什么时候开始,我变得连自己都觉得陌生。好像没有了特别喜欢的人,也没有了特别讨厌的人,更没有了特别要好的朋友。就连喜欢听歌都不是因为谁唱的多好听了,而是因为歌词,写的好像自己。




以上是关于基础算法,二叉树的层序遍历!的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点# leetcode算法题:二叉树的层序遍历

写算法—二叉树的层序遍历

算法20:求二叉树最宽的层有多少个节点(层序遍历续)

LeetCode Java刷题笔记—102. 二叉树的层序遍历

二叉树的层序遍历二叉树叶节点输出算法求二叉树的高度层序创建一棵二叉树

LeetCode二叉树的层序遍历