入门级别的面试题——LeetCode题目19:删除链表的倒数第N个节点

时间:2022-07-23
本文章向大家介绍入门级别的面试题——LeetCode题目19:删除链表的倒数第N个节点,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

原题描述

+

给定一个链表,删除链表的倒数第n个节点,并且返回链表的头结点,题目给定的 n 保证是有效的。你能尝试使用一趟扫描实现吗?

示例

输入:list=[1,2,3,4,5], n=2

输出:[1,2,3,5]

原题链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list

思路解析

+

记得找工作那时候刷题有两道入门级的题目印象深刻,一道题是找出链表是否有环,另一个就是这道题。

一趟扫描的思路是非常容易想到的。因为你知道要删除的节点距离末尾隔着n个节点,所以你只借助两个同时移动,但距离始终保持为n的指针就可以轻松实现。当前面的指针跑到结尾的时候,后面指针停留的位置恰好就是倒数第n个节点。

虽然思路非常简单,但是很少人能够在短时间内调通,因为面对的边界条件其实是有点讨厌的。所以凡是链表的题目,我都会加一个哑结点(头节点),这样可以方便处理任何case。

复杂度分析

+

  • 时间复杂度:
  • 空间复杂度:

计算步骤

+

1. 首先添加哑结点dummy,同时p指针和q指针都指向dummy;

2. 先让第一个指针q移动n步;

3. 同时移动指针p和q,直到q指向末尾(NULL);

最后一定要记得把哑结点和p指向的节点删掉。

C++参考代码

+

/**
 * Definition for singly-linked list.
 * struct ListNode {
 * int val;
 * ListNode *next;
 * ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *dummy = new ListNode(-1);
        dummy->next = head;

        ListNode *p = dummy, *q = dummy;
        while (n) { q = q->next; --n; }

        while (q->next != NULL) {
            p = p->next;
            q = q->next;
        }

        ListNode *rm = p->next;
        p->next = p->next->next;
        head = dummy->next;

        delete(rm);
        delete(dummy);

        return head;
    }
};