• 力扣:19-删除链表的倒数第N个结点


    题目描述

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

    示例 1:

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


    示例 2:

    输入:head = [1], n = 1
    输出:[]


    示例 3:

    输入:head = [1,2], n = 1
    输出:[1]
     

    提示:

    链表中结点的数目为 sz
    1 <= sz <= 30
    0 <= Node.val <= 100
    1 <= n <= sz


    进阶:一次扫描实现

    来源:力扣(LeetCode)

    解题思路 

    首先这道题是要删除链表的倒数第n个结点,一种容易想到的方法是,先遍历一下链表获得这个链表的长度,这样我们就可以获得要删除的结点正着数的位置了。我们创建一个新的链表,遍历一下题目所给链表,把遍历到的节点加到新链表中,遍历到要删除的结点时跳过即可,最后返回这个新链表即可。

    代码实现

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * ListNode *next;
    6. * ListNode() : val(0), next(nullptr) {}
    7. * ListNode(int x) : val(x), next(nullptr) {}
    8. * ListNode(int x, ListNode *next) : val(x), next(next) {}
    9. * };
    10. */
    11. class Solution {
    12. public:
    13. ListNode* removeNthFromEnd(ListNode* head, int n) {
    14. ListNode* m=new ListNode();//新链表
    15. ListNode* p=m;
    16. ListNode* k=head;
    17. int t=0;//链表长度
    18. while(k)//遍历链表获得链表长度
    19. {
    20. k=k->next;
    21. t++;
    22. }
    23. int w=t-n;//获得要删除的结点正着数的位置
    24. int j=1;
    25. while(head)
    26. {
    27. if(j==w+1)//遇到删除的节点跳过
    28. {
    29. head=head->next;
    30. j++;
    31. continue;
    32. }
    33. ListNode* q=new ListNode(head->val);
    34. p->next=q;//将遍历到的结点加入到新链表中
    35. p=q;
    36. head=head->next;
    37. j++;
    38. }
    39. return m->next;//返回新链表即可
    40. }
    41. };

    进阶要求我们扫描一次实现,想了半天没想出来,看了题解才知道要用双指针。双指针雀氏是一种非常妙的解法,没遇到这种题还真不好想出来。这道题用双指针就是用了一个前后指针,我们创建两个指针,一个前指针first,一个后指针second,我们让first超过second指针n个结点,那么first指针遍历到链表结尾的时候,second指针刚好就在倒数第n个结点,这样一次遍历是可以实现了。

    代码实现

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * ListNode *next;
    6. * ListNode() : val(0), next(nullptr) {}
    7. * ListNode(int x) : val(x), next(nullptr) {}
    8. * ListNode(int x, ListNode *next) : val(x), next(next) {}
    9. * };
    10. */
    11. class Solution {
    12. public:
    13. ListNode* removeNthFromEnd(ListNode* head, int n) {
    14. ListNode* p=new ListNode();
    15. p->next=head;
    16. ListNode* first=head;
    17. ListNode* second=p;
    18. for(int i=0;i
    19. {
    20. first=first->next;
    21. }
    22. while(first)
    23. {
    24. first=first->next;
    25. second=second->next;
    26. }
    27. second->next=second->next->next;
    28. return p->next;
    29. }
    30. };

    这道题还有一种解法,就是利用递归,递归也是一个非常好的想法,也很巧妙。按道理讲也是扫描了一次,下面是代码实现,仅供参考

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * ListNode *next;
    6. * ListNode() : val(0), next(nullptr) {}
    7. * ListNode(int x) : val(x), next(nullptr) {}
    8. * ListNode(int x, ListNode *next) : val(x), next(next) {}
    9. * };
    10. */
    11. class Solution {
    12. public:
    13. ListNode* removeNthFromEnd(ListNode* head, int n) {
    14. int ans=find(head,n);
    15. if(ans==n)
    16. return head->next;
    17. else
    18. return head;
    19. }
    20. int find(ListNode* node,int n)
    21. {
    22. if(node==nullptr)
    23. {
    24. return 0;
    25. }
    26. int res=find(node->next,n);
    27. if(res==n)
    28. {
    29. node->next=node->next->next;
    30. }
    31. return res+1;
    32. }
    33. };
  • 相关阅读:
    尚硅谷大数据项目《在线教育之实时数仓》笔记004
    java毕业设计家庭健康预警系统(附源码、数据库)
    如何公网远程访问本地WebSocket服务端
    【MySQL —— 数据库约束】
    【MYSQL】表的内外连接
    Citus 分布式 PostgreSQL 集群 - SQL Reference(SQL支持和变通方案)
    C语言内联汇编(详细)介绍附实例快速掌握
    服部周作《麦肯锡晋升法则》读书笔记 I
    初心、真心
    你敢信?仅靠一个JVM能够干掉91%的面试者?
  • 原文地址:https://blog.csdn.net/qq_52905520/article/details/126593959