友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi。因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

114. 二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。

  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

示例 1:

0114 01
输入: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]

提示:

  • 树中结点数在范围 [0, 2000] 内

  • -100 <= Node.val <= 100

进阶:你可以使用原地算法(\(O(1)\) 额外空间)展开这棵树吗?

思路分析

这道题本质上来讲可以说是要做一个先根遍历。但是,却可以将这个过程逆向过来,从底向上建立起关联。不可谓不精巧。

思考题:看题解中,可以逐级将左树并入到右树。尝试一下。

  • 一刷

  • 二刷

  • 三刷

  • 四刷

  • 五刷

  • 六刷

  • 七刷

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
 * Runtime: 0 ms, faster than 100.00% of Java online submissions for Flatten Binary Tree to Linked List.
 * Memory Usage: 38.4 MB, less than 40.00% of Java online submissions for Flatten Binary Tree to Linked List.
 *
 * Copy from: https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by--26/[详细通俗的思路分析,多解法 - 二叉树展开为链表 - 力扣(LeetCode)]
 */
private TreeNode pre;
public void flatten(TreeNode root) {
    if (Objects.isNull(root)) {
        return;
    }
    flatten(root.right);
    flatten(root.left);
    root.right = pre;
    root.left = null;
    pre = root;
}

/**
 * Runtime: 3 ms, faster than 29.55% of Java online submissions for Flatten Binary Tree to Linked List.
 * Memory Usage: 39.8 MB, less than 10.91% of Java online submissions for Flatten Binary Tree to Linked List.
 */
public void flattenQueue(TreeNode root) {
    Queue<TreeNode> queue = new ArrayDeque<>();
    preorder(root, queue);
    TreeNode current = queue.poll();
    while (!queue.isEmpty()) {
        current.right = queue.poll();
        current.left = null;
        current = current.right;
        if (Objects.nonNull(current)) {
            current.left = null;
        }
    }
}

private void preorder(TreeNode root, Queue<TreeNode> queue) {
    if (Objects.isNull(root)) {
        return;
    }
    queue.add(root);
    preorder(root.left, queue);
    preorder(root.right, queue);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 参考 https://leetcode.cn/problems/flatten-binary-tree-to-linked-list/solutions/17274/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by--26/[114. 二叉树展开为链表^] 的解法,自己实现的。
 */
public void flatten(TreeNode root) {
  if (root == null) {
    return;
  }
  while (root != 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;
    }
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2024-07-06 17:12:19
 */
public void flatten(TreeNode root) {
  if (root == null) {
    return;
  }
  while (root != null) {
    if (root.left != null) {
      TreeNode mostRight = root.left;
      while (mostRight.right != null) {
        mostRight = mostRight.right;
      }
      mostRight.right = root.right;
      root.right = root.left;
      root.left = null;
    }
    root = root.right;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2025-06-03 20:38:46
 */
public void flatten(TreeNode root) {
  if (root == null) {
    return;
  }
  while (root != null) {
    if (root.left != null) {
      TreeNode right = root.left;
      while (right.right != null) {
        right = right.right;
      }
      right.right = root.right;
      root.right = root.left;
      root.left = null;
    }
    root = root.right;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2025-11-10 22:50:45
 */
public void flatten(TreeNode root) {
  if (root == null) {
    return;
  }
  while (root != null) {
    // 直接判断 root.left 是否为 null,代码更简洁
    if (root.left != null) {
      TreeNode mostRight = mostRight(root.left);
      mostRight.right = root.right;
      root.right = root.left;
      root.left = null;
    }
    root = root.right;
  }
}

private TreeNode mostRight(TreeNode root) {
  TreeNode result = root;
  while (result != null && result.right != null) {
    result = result.right;
  }
  return result;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2025-11-11 20:07:06
 */
private TreeNode head;

public void flatten(TreeNode root) {
  if (root == null) {
    return;
  }
  flatten(root.right);
  flatten(root.left);
  root.left = null;
  root.right = head;
  head = root;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2026-10-20 22:44:41
 */
public void flatten(TreeNode root) {
  if (root == null) {
    return;
  }
  if (root.left != null) {
    TreeNode mostRight = root.left;
    while (mostRight.right != null) {
      mostRight = mostRight.right;
    }
    mostRight.right = root.right;
    root.right = root.left;
    root.left = null;
  }
  flatten(root.right);
}

思考题

如何使用递归来实现?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
 * 递归解决方案
 *
 * @author D瓜哥 · https://www.diguage.com
 * @since 2024-07-06 17:32:56
 */
public void flatten(TreeNode root) {
  if (root == null) {
    return;
  }
  flatten(root.left);
  flatten(root.right);

  TreeNode left = root.left;
  TreeNode right = root.right;

  root.left = null;
  root.right = left;

  TreeNode mostRight = root;
  while (mostRight.right != null) {
    mostRight = mostRight.right;
  }
  mostRight.right = right;
}