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

  1. 题目
    1. 示例:
    2. 进阶:
  2. 分析
    1. 代码
    2. Java 代码

题目

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

示例:

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

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

说明:给定的 n 保证是有效的。

进阶:

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

分析

  • 倒数第n个节点,求出链表长度len,走 len-n步,到达倒数第n个节点。

  • 双指针

    • 快指针先走n步,
    • 慢指针开始走,直到快指针走到链表尾部
      • 则慢指针当前指向倒数第n个节点

原理:len = m + n = n + m

  • 设总长度 len = m + n
    • 那么总长度也等于 len = n + m
    • 我们结合链表长度固定,让快指针先走n步,满指针走m步后
    • 快指针到达尾部,此时满指针就是指向n的第一个节点。

代码

// 头节点法、一趟遍历
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        
        ListNode* p = dummyHead;
        ListNode* q = dummyHead;
        
        for (int i = 0;i < n + 1;i++) {
            q = q->next;
        }
        
        while(q) {
            p = p->next;
            q = q->next;
        }
        
        ListNode* delNode = p->next;
        p->next = delNode->next;
        delete delNode;
        
        ListNode* retNode = dummyHead->next;
        delete dummyHead;
        
        return retNode;
    }
};

// 我的方法

ListNode* removeNthFromEnd(ListNode* head, int n) {
        // 异常处理
        if (head == nullptr) return nullptr;

        // 统计节点的总数
        ListNode* p = head;
        ListNode* pre = p;
        int count = 0;
        while (p != nullptr) {
            count++;
            pre = p;
            p = p->next;
        }

        // 特殊情况处理
        if (count < n) return head;
        if (count == n) {
            ListNode* t = head->next;
            delete head;
            return t;

        }
        if (n == 1) return pre;

        // 一般情况,倒数第n个节点,n = 1 || count
        ListNode* q = head;
        cout<<q->val<<" ";
        // 先走n步
        for (int i = 0;i < n; i++) {
            q = q->next;
            cout<<q->val<<" ";
        }
        cout<<endl;
        // 找倒数第n个节点
        p = pre = head;
        while (q != nullptr) {
            pre = p;
            cout<<"q = "<<q->val<<", p = "<<p->val<<" ";
            p = p->next;
            q = q->next;
        }
        cout<<endl;
        // 删除该节点
        ListNode* t = p;
        delete t;
        pre->next = p->next;

        return head;
    }

Java 代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */

 // way 1 两次遍历,辅助头节点
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 辅助头节点
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        int length = 0;
        // 统计总数
        ListNode first =  head;
        while(first != null) {
            length++;
            first = first.next;
        }
        
        //问题转换,求顺数第len - n个节点
        length-=n;
        first = dummy;
        while(length > 0) {
            length--;
            first = first.next;
        }
        
        first.next  = first.next.next;
        
        return dummy.next;
    }
}

// way 2,一次遍历,辅助头节点,双指针法
class Solution2 {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 辅助头节点
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        
        // 都从辅助头节点开始
        ListNode first =  dummy;
        ListNode second = dummy;
        
        // 先走n+1步
        for (int i = 1;i <= n+1;i++) {
            first = first.next;
        }
        
        // 问题转换,求顺数第len - n个节点
        while(first != null) {
            first = first.next;
            second = second.next;
        }
        
        second.next  = second.next.next;
        return dummy.next;
    }
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

💰

Title:19、删除链表的倒数第N个节点

Count:765

Author:攀登

Created At:2020-07-26, 00:19:44

Updated At:2024-06-20, 12:53:43

Url:http://jiafeimao-gjf.github.io/2020/07/26/19%E3%80%81%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B9/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

×

Help us with donation