1 題目描述
面試題32 - I. 從上到下打印二叉樹
從上到下打印出二叉樹的每個節點,同一層的節點按照從左到右的順序打印。
面試題32 - II. 從上到下打印二叉樹 II
從上到下按層打印二叉樹,同一層的節點按從左到右的順序打印,每一層打印到一行。
面試題32 - III. 從上到下打印二叉樹 III
請實現一個函數按照之字形順序打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右到左的順序打印,第三行再按照從左到右的順序打印,其他行以此類推。
2 解題思路
面試題32 - I. 從上到下打印二叉樹
-
方法 層序遍歷 BFS
題目要求的二叉樹的 從上至下 打印(即按層打印),又稱爲二叉樹的 廣度優先搜索(BFS)。
BFS 通常藉助 隊列 的先入先出特性來實現。
-
算法流程:
特例處理: 當樹的根節點爲空,則直接返回空列表 [] ;
初始化: 打印結果列表 res = [] ,包含根節點的隊列 queue = [root] ;
BFS 循環: 當隊列 queue 爲空時跳出;
(1)出隊: 隊首元素出隊,記爲 node;
(2)打印: 將 node.val 添加至列表 tmp 尾部;
(3)添加子節點: 若 node 的左(右)子節點不爲空,則將左(右)子節點加入隊列 queue ;
返回值: 返回打印結果列表 res 即可。
- 複雜度分析:
時間複雜度 O(N) : N 爲二叉樹的節點數量,即 BFS 需循環 N 次。
空間複雜度 O(N) : 最差情況下,即當樹爲平衡二叉樹時,最多有 N/2 個樹節點同時在 queue 中,使用 O(N) 大小的額外空間。
作者:jyd
鏈接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/solution/mian-shi-ti-32-i-cong-shang-dao-xia-da-yin-er-ch-4/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
面試題32 - II. 從上到下打印二叉樹 II
- 方法 :層序遍歷 BFS
- I. 按層打印: 題目要求的二叉樹的 從上至下 打印(即按層打印),又稱爲二叉樹的 廣度優先搜索(BFS)。BFS 通常藉助 隊列 的先入先出特性來實現。
- II. 每層打印到一行: 若將二叉樹從上至下分爲多層,則通過訪問 某層所有節點的 左右子節點 ,可統計出 下一層的所有節點 。根據此特性,可在打印本層全部節點時,將下一層全部節點加入隊列,以此類推,即可分爲多行打印。
- 算法流程:
特例處理: 當樹的根節點爲空,則直接返回空列表 [] ;
初始化: 打印結果列表 res = [] ,包含根節點的隊列 queue = [root] ;
BFS 循環: 當隊列 queue 爲空時跳出;
(1)新建一個臨時列表 tmp ,用於存儲當前層打印結果;
(2)當前層打印循環: 循環次數爲隊列 queue 長度(隊列中元素爲所有當前層節點);
2-1出隊: 隊首元素出隊,記爲 node;
2-2打印: 將 node.val 添加至列表 tmp 尾部;
2-3添加子節點: 若 node 的左(右)子節點不爲空,則將左(右)子節點加入隊列 queue ;
這裏是相比1 新加的地方 其他地方不變
(3)將當前層結果 tmp 添加入 res 。
(4)返回值: 返回打印結果列表 res 即可。
- 複雜度分析:
時間複雜度 O(N) : N 爲二叉樹的節點數量,即 BFS 需循環 N 次。
空間複雜度 O(N) : 最差情況下,即當樹爲平衡二叉樹時,最多有 N/2 個樹節點同時在 queue 中,使用 O(N) 大小的額外空間。
作者:jyd
鏈接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solution/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
面試題32 - III. 從上到下打印二叉樹 III
方法:層序遍歷 + 倒序
I. 樹的按層打印: 題目要求的二叉樹的 從上至下 打印(即按層打印),又稱爲二叉樹的 廣度優先搜索(BFS)。BFS 通常藉助 隊列 的先入先出特性來實現。
II. 每層打印到一行: 若將二叉樹從上至下分爲多層,則通過訪問 某層所有節點的 左右子節點 ,可統計出 下一層的所有節點 。根據此特性,可在打印本層節點時將下一層節點加入隊列,以此類推,即可分爲多行打印。
III. 打印順序交替變化: 根據題意,即實現 奇數層從左到右 , 偶數層從右到左 打印
。只需將所有偶數層的打印結果執行 倒序 即可。
作者:jyd
鏈接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er–3/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
3 解決代碼
面試題32 - I. 從上到下打印二叉樹
-
- 方法 層序遍歷 BFS 《Java代碼》
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int[] levelOrder(TreeNode root) {
if(root == null){
return new int[0];
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
ArrayList<Integer> ans = new ArrayList<>();
//當隊列 queue 爲空時跳出;
while(!queue.isEmpty()){
//出隊: 隊首元素出隊,記爲 node;
TreeNode node = queue.poll();
ans.add(node.val);
//添加左右節點
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
int[] res = new int[ans.size()];
for(int i = 0; i < ans.size(); i++){
res[i] = ans.get(i);
}
return res;
}
}
- 方法 層序遍歷 BFS 《python3代碼》
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[int]:
if not root:
return []
res = []
#collections 中的雙端隊列 deque() ,其 popleft() 方法可達到 O(1) 時間複雜度;
#列表 list 的 pop(0) 方法時間複雜度爲 O(N) 。
queue = collections.deque()
queue.append(root)
while queue:
#出隊: 隊首元素出隊,記爲 node;
node = queue.popleft()
res.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
面試題32 - II. 從上到下打印二叉樹 II
- 方法 層序遍歷 BFS 《Java代碼》
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root != null){
queue.add(root);
}
while(!queue.isEmpty()){
//構建tmp暫存
List<Integer> tmp = new ArrayList<>();
int size = queue.size();
for(int i = 0; i < size; i++){
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
//這裏是相比於1 新加的地方
res.add(tmp);
}
return res;
}
}
- 方法 層序遍歷 BFS 《python3代碼》
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = collections.deque()
queue.append(root)
while queue:
tmp = []
for _ in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left:queue.append(node.left)
if node.right:queue.append(node.right)
res.append(tmp)
return res
面試題32 - III. 從上到下打印二叉樹 III
- 方法:層序遍歷 + 倒序 《Java代碼》
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
//初始化res的格式要注意一下
List<List<Integer>> res = new ArrayList<>();
if(root != null){
queue.add(root);
}
while(!queue.isEmpty()){
List<Integer> tmp = new ArrayList<>();
//queue的大小是不斷變化的
int size = queue.size();
//當前層打印循環: 循環次數爲隊列 queue 長度(隊列中元素爲所有當前層節點
for(int i = 0; i < size; i++){
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
//偶數層倒序: 若 res 的長度爲 奇數 ,說明當前是偶數層,則對 tmp 執行 倒序 操作;
if(res.size() % 2 == 1) Collections.reverse(tmp);
res.add(tmp);
}
return res;
}
}
- 方法:層序遍歷 + 倒序 《python代碼》
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = collections.deque()
queue.append(root)
while queue:
tmp = []
for _ in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left:queue.append(node.left)
if node.right:queue.append(node.right)
#res.append(tmp[::-1] if len(res) % 2 else tmp)
if len(res) % 2:
res.append(tmp[::-1])
else:
res.append(tmp)
return res