每日算法:删除链表的倒数第N个节点

题目描述

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

思路

  1. 一次扫描实现的意思是我们要在循环中想办法寻找到倒数第n+1个节点,然后将他的next改掉;
  2. 既然题目给出了定长的空间,我们就要合理利用,使用片段移动的方式来确定倒数第n+1个节点;

代码

public class Demo03 {

    public static ListNode removeNthFromEnd(ListNode head, int n) {
        if(n == 0){
            return head;
        }
        //1.首先知道链表删除某元素是将上一个元素的next指向该元素的next元素。(跳过该元素)
        //2.那么使用额外的list集合,在遍历时将链表元素添加,即可得得到倒数第n,n+1,n-1节点。
        //将n+1赋值给n-1的next即可
        return null;
    }

    /**
     * 上边的方法采用了额外的集合来完成需求,增加了空间消耗
     * 1.既然要移除倒数第n个元素,说明n是确定的,那么如何能使得不借助“外力”在循环中找到倒数第n个元素呢;
     * 2.可以使用移动片段的方法;
     * 3.假设从倒数第n个元素到链表末尾长度为L,那么如果有一个长度为L的片段左侧从初始位置开始移动;
     * 4.当该片段的右侧到达链表末尾,理论上此时的左侧应该在倒数第n个元素处;
     * 5.那么依照此方式我们也可以找到第n-1个元素;
     * @param head
     * @param n
     * @return
     */
    public static ListNode removeNthFromEnd2(ListNode head, int n) {
        if(n == 0){
            return head;
        }
        //1.声明一个起始节点方便控制。
        ListNode listNode = new ListNode(0);
        listNode.next = head;
        ListNode first = listNode;
        ListNode end = listNode;
        //先让end元素往前移动n+1位
        for (int i = 1;i<=n+1;i++){
            end = end.next;
        }
        while (end!=null){
            first = first.next;
            end = end.next;
        }
        first.next = first.next.next;
        return listNode.next;
    }
}
class ListNode {
   int val;
     ListNode next;
    ListNode(int x) { val = x; }
 }

总结

  1. 读题要认真,找出题中隐藏的条件;
  2. 培养自己的抽象思维,想法要独特但不失理智;
  3. 尽可能的压缩空间和时间,并在平时写代码的时候注意加以运用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值