[劍指 offer]--樹--面試題32 - I. 從上到下打印二叉樹➕面試題32 - II. 從上到下打印二叉樹 II➕面試題32 - III. 從上到下打印二叉樹 III

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章