leetcode 力扣 114 二叉树展开为链表

54 阅读1分钟

方法一,空间复杂度为O(n),但是可读性最高

按先根遍历把节点放在列表里,然后遍历列表,连接节点

class Solution {
    List<TreeNode> nodes = new ArrayList<>();

    public void flatten(TreeNode root) {
        preorderTraversal(root);
        for (int i = 1; i < nodes.size(); i++) {
            TreeNode pre = nodes.get(i - 1), cur = nodes.get(i);
            pre.right = cur;
            pre.left = null;
        }
    }

    private void preorderTraversal(TreeNode root) {
        if (root != null) {
            nodes.add(root);
            preorderTraversal(root.left);
            preorderTraversal(root.right);
        }
    }
}

方法二,三指针遍历拼接

如果把二叉树展开为链表的话,根据先根遍历,根->左->右,左子树应该拼接在根节点的右边,右子树应该拼接在左子树的最右节点的右边,如下图,2应该接在1的右边,5应该接在4的右边,如此遍历下去

所以需要三个指针(注意防止空指针发生)
curr: 指向根节点,负责迭代
next: curr的左指针,负责寻找左子树
predecessor: 寻找左子树的最右节点

lc114_1.jpeg

lc114_2.jpeg

lc114_3.jpeg

lc114_4.jpeg

lc114_5.jpeg

lc114_6.jpeg

lc114_7.jpeg

lc114_8.jpeg

public void flatten(TreeNode root) {
        TreeNode curr = root;
        TreeNode next = null;
        TreeNode predecessor = null;

        while (curr != null) {
            if (curr.left != null) {
                next = curr.left;

                predecessor = next;
                while (predecessor.right != null) {
                    predecessor = predecessor.right;
                }

                predecessor.right = curr.right;
                curr.right = next;
                curr.left = null;
            }

            curr = curr.right;
        }
    }