LeetCode114.二叉树展开为链表

本文介绍了两种方法将二叉树转换为链表结构,一种使用额外空间,另一种空间复杂度降为O(1)。通过前序遍历操作,逐个节点调整指向,实现树节点的链式布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给定一个二叉树,将该树的节点展开成链表结构,并依次放到树的右节点上,(顺序为前序遍历的顺序),每个节点的左子树都置为null。

思路:

方法一

我们首先能想到的就是前序遍历一遍二叉树,将节点放入到一个list集合中,然后依次更改原二叉树的节点指向,使其成为一个链表结构

以下为代码+注释,结合代码和注释应该好理解一点:

//首先定义TreeNode节点
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val){
        this.val = val;
    }
}
public TreeNode flatten(TreeNode root){
		if(root == null)
			return root;
        List<TreeNode> list = new ArrayList<>();
        //将二叉树前序遍历的节点依次放入list集合中
        preorder(root, list);
        int len = list.size();
        for (int i = 0; i < len - 1; i++) {
            //取出当前节点,重新调整左右子树的节点值
            TreeNode cur = list.get(i);
            //将当前节点的左节点置为null
            cur.left = null;
            //该节点在list集合中的下一个节点就是它的右子树节点
            cur.right = list.get(i + 1);
        }
        return root;
    }
	// 前序遍历二叉树
    public void preorder(TreeNode root, List list) {
        if (root != null) {
            list.add(root);
            preorder(root.left, list);
            preorder(root.right, list);
        }
    }
方法二

能不能找到一种不使用额外空间,让空间复杂度降到O(1)的做法?
当然有。
思考一下,将一个二叉树展开为链表,假设一个当前节点cur,因为前序遍历的顺序就是:头节点,左子树,右子树。
那么展开其实就是将当前节点cur左子树上前序遍历的最后一个节点指向了cur右子树的第一个节点(主要思想),之后再将指针重新赋值

以下为代码+注释:


public void flatten(TreeNode root) {
        if(root == null)
            return;
        // 因为每个节点的左子树前序遍历的最后一个节点的下一个就是右子树的第一个节点,
        // 因此可以在递归的时候就做好记录并直接进行连接
        // 先设置一个cur指针指向当前节点
        TreeNode cur = root;
        while(cur != null){
            if(cur.left != null){
                // 记录当前节点的下一个节点,最后要用
                TreeNode next = cur.left;
                // 设置一个前驱节点,最后要让它指向当前节点的右节点
                TreeNode pre = next;
                // 不停遍历直到pre指向当前节点左子树的最后一个遍历到的节点
                while(pre.right != null){
                    pre = pre.right;
                }
                // 将前驱节点的下一个指向当前节点的右子树第一个节点
                pre.right = cur.right;
                // 当前节点的左子树设置为null
                cur.left = null;
                // 当前节点的右子树节点指向前驱节点
                cur.right = next;
            }
            // 当前节点继续向下走
            cur = cur.right;
        }
        return root;
    }

以上所有文字均为我本人所写,我也是在不断学习之中,如有错误,欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值