删除链表的倒数第N个节点

69 篇文章 1 订阅
63 篇文章 0 订阅

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
(1)方法:笨方法(两遍遍历)
思路:
1,第一次遍历找到给定链表的长度;
2,要删除倒数第n个节点,其实就是让删除length-n+1那个节点,也就是让第length-n节点的下个节点指向length-n+2即可;
注意:为了防止链表只有一个节点,还删除一个节点,可以在链表前面加一个哑结点,避免这种极端情况

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        //笨方法,首先要知道head共有多少个节点,也就是长度
        //就是定义一个哑结点让它指向head的头结点,避免极端(只有一个的情况)
        ListNode test = new ListNode(0);
        test.next  = head;
        int len = 0;
        //定义一个临时链表,接受head的全部改变长度,直到没有,测长度
        ListNode temp = head;
        while (temp != null) {
            len ++;
            temp = temp.next;
        }
        //定义删除节点的前一个节点位置,删除节点为len-n+1;
        len = len - n;
        temp = test;
        while (len > 0) {
            temp = temp.next;
            len --;
        }
        temp.next =temp.next.next;
        return test.next;
    }
}

(2)方法:双指针遍历法
思路:
1,大概思路和上一个方法思路差不多;
2,因为要删除的节点是length-n的下一个节点,所以我们的目的是让第一个指针先走一段,再让第二个指针和第一个指针一起走,直到第一个走完全部,让第二个指针刚好在length-n这个节点;
3,假设第一个指针先走x个节点,那么就会有第二个节点走的节点有length-x个,从第一个节点往后走(也就是其实是从2开始),所以存在关系
1+length-x=length-n; => 得出结论 x = n + 1;第一个指针先走n + 1 步,就可以保证第二个指针停在length - n的位置,也就是让他们的间隔保证为n;
注意:都加了哑结点在前面,防止只存在一个元素情况下的角标越界异常。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        //避免极端情况,可以定义一个哑结点
        ListNode test = new ListNode(0);
        test.next = head;
        //双指针遍历,
        ListNode first = test;
        ListNode second = test;
        //first先走n个节点
        for (int i = 1; i <= n + 1; i ++) {
            first = first.next;
        }
        //第一个指针和第二个一起走
        while (first != null) {
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        return test.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值