1. 題目
給你二叉樹的根結點 root ,請你將它展開為一個單鏈表:
- 展開后的單鏈表應該同樣使用 TreeNode ,其中 right 子指針指向鏈表中下一個結點,而左子指針始終為null 。
- 展開后的單鏈表應該與二叉樹 先序遍歷 順序相同。
示例 1:
輸入:root = [1,2,5,3,4,null,6]
輸出:[1,null,2,null,3,null,4,null,5,null,6]
示例 2:
輸入:root = []
輸出:[]
示例 3:
輸入:root = [0]
輸出:[0]
2. 題解
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public void flatten(TreeNode root) {while (root != null) { //左子樹為 null,直接考慮下一個節點if (root.left == null) {root = root.right;} else {// 找左子樹最右邊的節點TreeNode pre = root.left;while (pre.right != null) {pre = pre.right;} //將原來的右子樹接到左子樹的最右邊節點pre.right = root.right;// 將左子樹插入到右子樹的地方root.right = root.left;root.left = null;// 考慮下一個節點root = root.right;}}}
}
3. 解析
出自:詳細通俗的思路分析,多解法
1-3行:這是對TreeNode類的定義或者說結構體的定義,它是一棵二叉樹,其中每個節點最多有兩個子節點,一個左子節點和一個右子節點。如果沒有提供值、左子節點或右子節點,它們將默認為null。
7-23行:這些代碼定義了一個名為Solution的類,其中包含了一些與二叉樹相關的方法。這段代碼的主要功能是將二叉樹展開成鏈表形式。
8行:在展開二叉樹之前,會檢查根節點是否為null。如果為null,則直接返回,不需要進行任何操作。
10-23行:這是一個while循環,一直執行直到遇到一棵完全沒有左子樹的樹,此時root.left將為null,我們只需考慮右子樹即可。在這種情況下,代碼直接將根節點的值賦給根節點,然后將其右指針移到原來的右子樹上。
12-20行:如果左子樹不為空,那么找左子樹最右邊的節點。這個節點我們假設它為pre。
14-16行:將原來的右子樹接到左子樹的最右邊節點的右指針上。
18行:然后將左子樹移動到右子樹的位置,并置空左子樹。
20行:最后考慮下一個節點,也就是現在的根節點的右子節點。代碼會一直執行直到遇到一棵完全沒有左子樹的樹,此時root.left將為null,我們只需考慮右子樹即可。
在這段代碼中,我們使用了類似于后序遍歷(DFS)的方法來展開二叉樹。我們在處理每個節點時,都將其視作一個鏈表的一部分,然后再移動到下一個節點。這樣就可以將一棵二叉樹“展平”為一條單鏈表。