leetcode刷题(36)——114.二叉树展开为链表

一、题目

给定一个二叉树,原地将它展开为链表。
在这里插入图片描述

二、思路及代码

根据题意,二叉树展开的链表的顺序就是二叉树前序遍历的结果。

思路一:

先求出二叉树的前序遍历序列,再转换为链表。

注意:

转换成的链表仍然是用树结构存储,就是存储在每个节点的右孩子处,而左孩子为空。

代码实现:

class Solution {
    public void flatten(TreeNode root) {
        if(root == null)
            return;
        LinkedList<TreeNode> list = new LinkedList<>();
        preOrder(root, list);
        TreeNode head = list.pop();
        head.left = null;
        while(!list.isEmpty()){
            TreeNode temp = list.pop();
            temp.left = null;
            head.right = temp;
            head = head.right;
        }
    }

    public void preOrder(TreeNode root, LinkedList<TreeNode> list){
        if(root == null)
            return;
        list.add(root);
        preOrder(root.left, list);
        preOrder(root.right, list);
    }
}

思路二:

思路一实际上是利用队列作为辅助工具完成转换,我们也可以利用栈来完成转换。

前序遍历顺序为:根节点——》左子树——》右子树。所以在入栈时,先将左孩子入栈,再将右孩子入栈,这样的话先弹出的就是左孩子。

代码实现:

class Solution {
    public void flatten(TreeNode root) {
        if(root == null)
            return;
        LinkedList<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        TreeNode head = new TreeNode(-1);;
        while(!stack.isEmpty()){
            TreeNode temp = stack.pop();
            head.left = null;
            head.right = temp;
            // 先将右孩子入栈
            if(temp.right != null)
                stack.push(temp.right);
            // 再将左孩子入栈
            if(temp.left != null)
                stack.push(temp.left);
            head = head.right;
        }
    }
}

思路三:(递归)

假如有一棵二叉树:

  1
 / \
2	3

转换为链表的过程如下:

  • 根节点的右子树变成根节点的左子树的右子树;

       1
      /
     2
      \
       3
    
  • 根节点的左子树变成根节点的右子树;

     1
      \
       2
        \
         3
    

所以,对于任意一棵树,可以递归的完成该过程。假设左、右子树已经递归地转换成链表,则再进行上面两步,就可完成整棵树的转换,即

  • 将右子树挂到左子树的右叶子上
  • 再将整棵左子树挂到根节点的右边

代码如下:

class Solution {
    public void flatten(TreeNode root) {
        if(root == null)
            return;
        flatten(root.right);
        flatten(root.left);
        if(root.left != null){
            TreeNode node = root.left;
            // 找到左孩子的右叶子
            while(node.right != null){
                node = node.right;
            }
            node.right = root.right;// 将右子树挂到左子树的右叶子上
            root.right = root.left;// 再将整棵左子树挂到根节点的右边
            root.left = null;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值