删除链表的倒数第 N 个结点(双指针)

4 篇文章 0 订阅
4 篇文章 0 订阅

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

LeetCode19
题目描述:
在这里插入图片描述
要做的有两件事:一找到要删除的节点,二让这个节点的前面一个节点指向要删除节点的后一个节点

1. 三指针法
这个方法是自己想的有点繁琐。定义三个指针,一个记录要删除的节点,一个记录待删除节点的前一个节点,最后一个用于遍历。对头节点要另外做处理。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head.next == null) return null;
        ListNode cur = head;
        ListNode tmp = head; //当前检查的节点
        ListNode pre = head; //当前检查的节点的前一个节点
        int m = n;
        while(tmp != null){
            while(n >= 0){
                if(cur == null){
                    if(tmp == head){ //如果被删除节点是头节点
                        ListNode newHead = head.next;
                        head.next = null;
                        return newHead;
                    }else{
                        pre.next = tmp.next;
                        return head;
                    }
                }
                cur = cur.next;
                n--;
            }
            pre = tmp;
            tmp = tmp.next;
            cur = tmp;
            n = m;
        }
        return head;
    }
}

2. 利用哑节点优化一下
看了官解之后学到的。一般这种要删除节点,最好定义一个哑结点,让它的下一个节点指向head,这样就不用对头节点做另外的处理。那么上面的代码就可以优化成:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0,head);
        ListNode cur = dummy;
        ListNode tmp = dummy; //当前检查的节点
        ListNode pre = dummy; //当前检查的节点的前一个节点
        int m = n;
        while(tmp != null){
            while(n >= 0){
                if(cur == null){ //找到要删除的节点
                    pre.next = tmp.next;
                    return dummy.next;  
                }
                cur = cur.next;
                n--;
            }
            pre = tmp;
            tmp = tmp.next;
            cur = tmp;
            n = m;
        }
        return dummy.next;
    }
}

3.继续优化成双指针
定义一个慢指针slow,一个快指针fast,两者初始都指向哑节点,先让fast向前移n步,然后同时移动slow和fast,当fast指向链表尾部时,slow的下一个节点就是要删除的节点。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0,head);
        ListNode slow = dummy;
        ListNode fast = dummy; 
        while(n > 0){
            fast = fast.next;
            n--;
        }
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return dummy.next;     
    }
}

时间复杂度:O(L)
空间复杂度:O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值