//Java class Solution { public Node connect(Node root) { if (root == null) { return null; } Queue<Node> queue = new ArrayDeque<Node>(); queue.offer(root); while (!queue.isEmpty()) { int n = queue.size(); Node last = null; for (int i = 1; i <= n; ++i) { Node f = queue.poll(); if (f.left != null) { queue.offer(f.left); } if (f.right != null) { queue.offer(f.right); } if (i != 1) { last.next = f; } last = f; } } return root; } }
复杂度分析
记树上的点的个数为 N。
时间复杂度:O(N)。我们需要遍历这棵树上所有的点,时间复杂度为 O(N)。
空间复杂度:O(N)。即队列的空间代价。
(2)指针
思路及算法
因为必须处理树上的所有节点,所以无法降低时间复杂度,但是可以尝试降低空间复杂度。
在方法一中,因为对树的结构一无所知,所以使用队列保证有序访问同一层的所有节点,并建立它们之间的连接。然而不难发现:一旦在某层的节点之间建立了 next 指针,那这层节点实际上形成了一个链表。因此,如果先去建立某一层的 next 指针,再去遍历这一层,就无需再使用队列了。
基于该想法,提出降低空间复杂度的思路:如果第 iii 层节点之间已经建立 next 指针,就可以通过 next 指针访问该层的所有节点,同时对于每个第 i 层的节点,我们又可以通过它的 left 和 right 指针知道其第 i+1 层的孩子节点是什么,所以遍历过程中就能够按顺序为第 i+1 层节点建立 next 指针。
具体来说:
从根节点开始。因为第 0 层只有一个节点,不需要处理。可以在上一层为下一层建立 next 指针。该方法最重要的一点是:位于第 x 层时为第 x+1 层建立 next 指针。一旦完成这些连接操作,移至第 x+1 层为第 x+2 层建立 next 指针。
当遍历到某层节点时,该层节点的 next 指针已经建立。这样就不需要队列从而节省空间。每次只要知道下一层的最左边的节点,就可以从该节点开始,像遍历链表一样遍历该层的所有节点。