vlambda博客
学习文章列表

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

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

若二叉树非空(假设其高度为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岁,四年过去了,等到自己去经历这句话的时候,我发现要完完全全地做到这句话真的是太难太难了,心碎的滋味真的很难受。

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


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