⭐算法入门⭐《链表》中等01 —— LeetCode 19. 删除链表的倒数第 N 个结点

饭不食,水不饮,题必须刷

C语言免费动漫教程,和我一起打卡!
光天化日学C语言

LeetCode 太难?先看简单题!
C语言入门100例

数据结构难?不存在的!
数据结构入门

LeetCode 太简单?算法学起来!
夜深人静写算法

文章目录

  • 一、题目
    • 1、题目描述
    • 2、基础框架
    • 3、原题链接
  • 二、解题报告
    • 1、思路分析
    • 2、时间复杂度
    • 3、代码详解
  • 三、本题小知识

一、题目

1、题目描述

  给你一个链表,删除链表的倒数第 n n n 个结点,并且返回链表的头结点。
  样例输入: h e a d = [ 1 , 2 , 3 , 4 , 5 , 6 ] head = [1,2,3,4,5,6] head=[1,2,3,4,5,6] n = 5 n = 5 n=5
  样例输出: [ 1 , 3 , 4 , 5 , 6 ] [1,3,4,5,6] [1,3,4,5,6]

2、基础框架

  • c++ 版本给出的基础框架代码如下:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
    }
};
  • 这里引入了一种数据结构 链表 ListNode
  • 成员有两个:数据域val和指针域next
  • 返回的是链表的某个结点;

3、原题链接

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

二、解题报告

1、思路分析

  • 我们可以通过一个 O ( n ) O(n) O(n) 的枚举,将所有的链表节点按照顺序放进一个数组中,于是,对于一个长度为 L L L 的链表。

我们采用数学归纳法:
  如果删除的是倒数第 1 1 1 个,则删除数组的第 L − 1 L-1 L1 个元素,再把原数组组织成链表;
  如果删除的是倒数第 2 2 2 个,则删除数组的第 L − 2 L-2 L2 个元素,再把原数组组织成链表;
  如果删除的是倒数第 3 3 3 个,则删除数组的第 L − 3 L-3 L3 个元素,再把原数组组织成链表;
  …
  如果删除的是倒数第 L L L 个,则删除数组的第 0 个链表节点,再把原数组组织成链表;

  • 所以我们可以先做一次遍历,重新组织一个新的链表,并且将第 L − n L - n Ln 忽略;再返回链表头结点即可。

2、时间复杂度

  • 线性枚举为 O ( n ) O(n) O(n)

3、代码详解

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        vector <ListNode*> nodes;
        ListNode *now = head;
        while(now) {
            nodes.push_back(now);                     // (1)
            now = now->next;
        }
        if(n == nodes.size()) {
            head = head->next;                        // (2)
        }else {
            ListNode *last = head;
            for(int i = 1; i < nodes.size(); ++i) {
                if(i == nodes.size() - n) {
                    continue;                         // (3)
                }
                last->next = nodes[i];                // (4)
                last = nodes[i];
            }
            last->next = NULL;
        }
        return head;
    }
};
  • ( 1 ) (1) (1) 通过一个 O ( n ) O(n) O(n) 的枚举,将所有的链表节点按照顺序放进一个数组中;
  • ( 2 ) (2) (2) 当删除倒数最后一个元素时,直接将根节点指向它的next即可;
  • ( 3 ) (3) (3) 需要删除的节点,不再组织到链表中;
  • ( 4 ) (4) (4) last代表当前链表最后一个元素;

三、本题小知识

链表问题如果在时间复杂度允许的情况下,是可以用数组来代替的;


你可能感兴趣的:(《LeetCode算法全集》,算法,链表,数据结构,c++,枚举)