首页 > 其他分享 >leetcode 19.删除链表的倒数第N个节点

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

时间:2024-01-15 15:47:09浏览次数:28  
标签:ListNode 19 next 链表 second 节点 leetcode first

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

第十九题:删除链表的倒数第N个节点

在对链表进行操作时,一种常用的技巧是添加一个哑节点(dummy node),它的 next指针指向链表的头节点。这样一来,我们就不需要对头节点进行特殊的判断了。

例如,在本题中,如果我们要删除节点 y,我们需要知道节点 y 的前驱节点 x,并将 x的指针指向 y 的后继节点。但由于头节点不存在前驱节点,因此我们需要在删除头节点时进行特殊判断。但如果我们添加了哑节点,那么头节点的前驱节点就是哑节点本身,此时我们就只需要考虑通用的情况即可。

1.快慢指针:

由于我们需要找到倒数第 n个节点,因此我们可以使用两个指针 first和 second 同时对链表进行遍历,并且 first比 second超前 n 个节点。当 first遍历到链表的末尾时,second就恰好处于倒数第 n个节点。

具体地,初始时 first和 second均指向头节点。我们首先使用 first对链表进行遍历,遍历的次数为 n。此时,first和 second之间间隔了 n−1个节点,即 first比 second超前了 n个节点。

在这之后,我们同时使用 first和 second对链表进行遍历。当 first遍历到链表的末尾(即 first为空指针)时,second恰好指向倒数第 n 个节点。

  • 时间复杂度:O(L),其中 L是链表的长度。
  • 空间复杂度:O(1)。
public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        ListNode first = head;
        ListNode second = dummy;
        for (int i = 0; i < n; ++i) {
            first = first.next;
        }
        while (first != null) {
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        ListNode ans = dummy.next;
        return ans;

    }

2.栈:

我们也可以在遍历链表的同时将所有节点依次入栈。根据栈「先进后出」的原则,我们弹出栈的第 n 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点。这样一来,删除操作就变得十分方便了。

  • 时间复杂度:O(L),其中 L是链表的长度。
  • 空间复杂度:O(L)。其中 L 是链表的长度。主要为栈的开销。
public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        Deque<ListNode> stack = new LinkedList<ListNode>();
        ListNode cur = dummy;
        while (cur != null) {
            stack.push(cur);
            cur = cur.next;
        }
        for (int i = 0; i < n; ++i) {
            stack.pop();
        }
        ListNode prev = stack.peek();
        prev.next = prev.next.next;
        ListNode ans = dummy.next;
        return ans;
    }


3.两次遍历:

一种容易想到的方法是,我们首先从头节点开始对链表进行一次遍历,得到链表的长度 L。随后我们再从头节点开始对链表进行一次遍历,当遍历到第 L−n+1 个节点时,它就是我们需要删除的节点。

为了与题目中的 n 保持一致,节点的编号从 1 开始,头节点为编号 1 的节点。

为了方便删除操作,我们可以从哑节点开始遍历 L−n+1个节点。当遍历到第 L−n+1 个节点时,它的下一个节点就是我们需要删除的节点,这样我们只需要修改一次指针,就能完成删除操作。

  • 时间复杂度:O(L),其中 L是链表的长度。
  • 空间复杂度:O(1)。
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        int length = getLength(head);
        ListNode cur = dummy;
        for (int i = 1; i < length - n + 1; ++i) {
            cur = cur.next;
        }
        cur.next = cur.next.next;
        ListNode ans = dummy.next;
        return ans;
    }

    public int getLength(ListNode head) {
        int length = 0;
        while (head != null) {
            ++length;
            head = head.next;
        }
        return length;
    }
}

标签:ListNode,19,next,链表,second,节点,leetcode,first
From: https://www.cnblogs.com/ldy20020324/p/17965489

相关文章

  • WindowsServer 2019安装域服务
    WindowsServer2019安装域服务导航目录WindowsServer2019安装域服务导航一、重命名主控服务器固定IP地址重命名域控服务器二、登录并创建服务三、检验安装域服务一、重命名主控服务器固定IP地址右击电脑右下角网络的标志,点击打开“网络和internet”设置,在屏幕中间的......
  • Codeforces Round 919 (Div. 2)(A~D) 题解
    CodeforcesRound919(Div.2)(A~D)题解A.SatisfyingConstraints题意:给你一些条件让你求出满足条件的整数有多少个。模拟即可。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constllMAXN=2e5+5;llTex=1,n;voidAC(){ cin>>n; lll=......
  • 每日一题 2024-1-15 删除排序链表中的重复元素Ⅱ
    1.题目(中等)原题链接给定一个已排序的链表的头\(head\),删除原始链表中所有重复数字的节点,只留下不同的数字。返回已排序的链表。示例1:输入:head=[1,2,3,3,4,4,5]输出:[1,2,5]示例2:输入:head=[1,1,1,2,3]输出:[2,3]提示:链表中节点数目在范围\([0,300]\)......
  • 【算法】【线性表】【链表】K 个一组翻转链表
    1 题目给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。示例1:......
  • 经典数据结构题目-链表
    链表707.设计链表解题思路参考官方的单向链表,设置一个成员变量作为虚拟头节点,一个成员变量size保存有效节点数代码publicMyLinkedList(){size=0;head=newListNode(0);}publicintget(intindex){if(index<0||index>=size){retur......
  • #yyds干货盘点# LeetCode程序员面试金典:移除盒子
    题目给出一些不同颜色的盒子boxes,盒子的颜色由不同的正数表示。你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续k个盒子(k>=1),这样一轮之后你将得到k*k个积分。返回你能获得的最大积分和。 示例1:输入:boxes=[1,3,2,......
  • #yyds干货盘点# LeetCode程序员面试金典:整数替换
    题目给定一个正整数n,你可以做如下操作:如果n是偶数,则用n/2替换n。如果n是奇数,则可以用n+1或n-1替换n。返回n变为1所需的最小替换次数。 示例1:输入:n=8输出:3解释:8->4->2->1示例2:输入:n=7输出:4解释:7->8->4->2->1或7->6-......
  • 10.19
    继承 publicclassParentChildTest{publicstaticvoidmain(String[]args){Parentparent=newParent();parent.printValue();Childchild=newChild();child.printValue();parent=child;parent.printValue();......
  • leetcode 跳跃游戏
    classSolution{public:boolcanJump(vector<int>&nums){intn=nums.size();intcurrent_length=nums[0];if(n==1)returntrue;if(current_length==0)returnfalse;for(inti=1;i<n;i......
  • MySQL修改安全策略时报错:ERROR 1193 (HY000): Unknown system variable ‘validate_pa
    我使用的版本是MySQL5.73,环境是LinuxCentOS7,其他版本不知道是否可行,望谅解。当我们想设置简单的密码的时候,看了别人发的如何修改安全策略的代码,如下:setglobalvalidate_password_policy=0;setglobalvalidate_password_length=1;但是当我们使用的时候,却报了这样一个......