LeetCode题解 11 (114,19) 二叉树展开为链表,删除链表的倒数第 N 个结点

二叉树展开为链表(114)

题目
根据题意这里我们需要将1个二叉树转成类似于链表的形式,同时是根据先序遍历(什么是先序遍历?),这里采用的是展开左子树和右子树,并将左子树添加到右子树上,不再新建空间。

先获取左右子树

//展开左右子树
        TreeNode l = listTree(root.left);
        TreeNode r = listTree(root.right);

第一种情况:如果左子树为null,那么我们就直接将右子树展平添加即可,

 //如果左子树是null的话,就直接添加右子树
        if(l == null){
            root.right = r;
        }

第二种情况:如果左子树不为null,我们就需要先将左子树展开添加,再遍历到刚添加左子树的末尾添加右子树。

       else{
            root.right = l;
            //记录最右边的树的根部
            TreeNode rightTree = l;
            while(rightTree.right != null){
                rightTree = rightTree.right;
            }
            rightTree.right = r;
            root.left = null;
        }

这里我们为了能够找到左子树的最低端,我们要不断的去往右进行遍历再最底部再添加右子树

代码解答:

class Solution {
    public void flatten(TreeNode root) {
         if(root == null){
             return ;
         }
        root = listTree(root);
    }
    public TreeNode listTree(TreeNode root){
        if(root == null){
            return null;
        }
        //展开左右子树
        TreeNode l = listTree(root.left);
        TreeNode r = listTree(root.right);
        //如果左子树是null的话,就直接添加右子树
        if(l == null){
            root.right = r;
        }else{
            root.right = l;
            //记录最右边的树的根部
            TreeNode rightTree = l;
            while(rightTree.right != null){
                rightTree = rightTree.right;
            }
            rightTree.right = r;
            root.left = null;
        }
      return root;
    }
}

删除链表的倒数第 N 个结点(19)

题目
这道题的难点是怎么找到链表的倒数第n个节点,
这里我们使用快慢指针来解决,首先我们先让快指针走n步,当走完n步时,这时我们让满指针和快指针一起走,当快指针走到末尾是,满指针所指的位置恰好是倒数第n个节点的上一个节点。

//创建2个指针
        ListNode fast = head;
        ListNode slow = head;
        //先让快指针走n步
        for(int i = 1;i<=n;i++){
            fast = fast.next;
        }

当然这里有一个特殊情况就是当我们要删除倒数第5个节点时,也就是删除第一个节点,那么快指针走到了末尾,因此我们要做一次判断

    //就表示快指针走到了链表的尾部,及要删除的是链表的第一个节点
        if(fast == null){
            //返回除头节点后的其他节点
            return head.next;
        }

因此这样我们就得到了倒数第n个节点,之后的删除中间节点就简单了,我们让当前指针所指的节点的next值指向后面的值(跳过要删除的那个节点)。

//接着满指针和快指针一起走
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;

代码解答:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
       //如果链表为Null就返回null
        if(head == null || head.next == null){
            return null;
        }
        //创建2个指针
        ListNode fast = head;
        ListNode slow = head;
        //先让快指针走n步
        for(int i = 1;i<=n;i++){
            fast = fast.next;
        }
        //就表示快指针走到了链表的尾部,及要删除的是链表的第一个节点
        if(fast == null){
            //返回除头节点后的其他节点
            return head.next;
        }
        //接着满指针和快指针一起走
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return head;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱敲键盘的程序源

你的激励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值