首页 > 其他分享 >19_删除链表的倒数第N个结点

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

时间:2024-09-13 15:02:14浏览次数:10  
标签:head ListNode 19 next 链表 int 节点 倒数第

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

【问题描述】

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

示例一:
输入:head = [1], n = 1
输出:[]

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

提示:

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

【算法设计思想】

在解决本题时,笔者主要是进行了一次遍历链表得到了其长度length,然后再用总长度length减去n得到我们的target,进而问题就迎刃而解了。

在这里我们复习一下单链表中的经典关键语句,求长度的代码:

int length = 0;

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

或者这样写:

int length = 1;

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

【算法描述】

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:
    /**
     * 删除链表中倒数第 n 个节点,并返回链表的头节点
     *
     * @param head 链表的头节点指针
     * @param n 需要删除的倒数第 n 个节点
     * @return 返回删除节点后的链表头指针
     */
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // 1. 计算链表的长度
        ListNode* p = head;
        int length = 1;  // 从1开始计数
        while (p->next != nullptr) {
            length++;
            p = p->next;
        }
        
        // 2. 计算需要删除节点的正向位置
        int target = length - n;
        
        // 3. 如果需要删除的是头节点
        if (target == 0) {
            ListNode* temp = head;      // 保存当前头节点的指针
            head = head->next;          // 更新头节点指针
            delete temp;                // 删除原头节点
            return head;                // 返回新的头节点
        }
        
        // 4. 遍历到目标节点的前一个节点
        ListNode* prev = head;
        for (int i = 0; i < target - 1; i++) {
            prev = prev->next;
        }
        
        // 5. 删除目标节点
        ListNode* temp = prev->next;    // 目标节点
        prev->next = temp->next;        // 跳过目标节点,重新连接链表
        delete temp;                    // 删除目标节点
        
        // 6. 返回删除后的链表头节点
        return head;
    }
};

Java:

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

class Solution {
    /**
     * 删除链表中倒数第 n 个节点,并返回链表的头节点
     * 
     * @param head 链表的头节点
     * @param n 需要删除的倒数第 n 个节点
     * @return 返回删除节点后的链表头节点
     */
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 1. 计算链表的长度
        int length = 1;
        ListNode p = head;
        while (p.next != null) {
            length++;
            p = p.next;
        }
        
        // 2. 计算需要删除节点的正向位置
        int target = length - n;
        
        // 3. 如果需要删除的是头节点
        if (target == 0) {
            ListNode temp = head;   // 保存当前头节点
            head = head.next;       // 更新头节点为下一个节点
            temp = null;            // 将原头节点引用设为 null,帮助垃圾回收
            return head;            // 返回新的头节点
        }

        // 4. 遍历到目标节点的前一个节点
        ListNode prev = head;
        for (int i = 0; i < target - 1; i++) {
            prev = prev.next;    // 移动到目标节点的前一个节点
        }

        // 5. 删除目标节点
        ListNode temp = prev.next;   // 目标节点
        prev.next = temp.next;       // 跳过目标节点,重新连接链表
        temp = null;                 // 将目标节点引用设为 null,帮助垃圾回收
        
        // 6. 返回删除后的链表头节点
        return head;
    }
}

Python:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        # 1. 计算链表的长度
        p = head
        length = 1  # 初始化长度为1,因为我们将至少有一个节点
        while p.next is not None:
            length += 1  # 遍历链表,增加长度
            p = p.next  # 移动指针到下一个节点

        # 2. 计算需要删除节点的正向位置
        target = length - n
        
        # 3. 如果需要删除的是头节点
        if target == 0:
            temp = head  # 保存当前头节点
            head = head.next  # 更新头节点为下一个节点
            del temp  # 删除原头节点
            return head  # 返回新的头节点
        
        # 4. 遍历到目标节点的前一个节点
        prev = head
        for i in range(target - 1):
            prev = prev.next  # 移动指针到目标节点的前一个节点
        
        # 5. 删除目标节点
        temp = prev.next  # 目标节点
        prev.next = temp.next  # 跳过目标节点,重新连接链表
        del temp  # 删除目标节点
        
        # 6. 返回删除后的链表头节点
        return head

C:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    // 1. 计算链表的长度
    struct ListNode* p = head;
    int length = 1;  // 初始化长度为1,因为我们将至少有一个节点
    while (p->next != NULL) {
        length++;
        p = p->next;  // 移动指针到下一个节点
    }

    // 2. 计算需要删除节点的正向位置
    int target = length - n;

    // 3. 如果需要删除的是头节点
    if (target == 0) {
        struct ListNode* temp = head;  // 保存当前头节点
        head = head->next;            // 更新头节点为下一个节点
        free(temp);                   // 释放原头节点的内存
        return head;                 // 返回新的头节点
    }

    // 4. 遍历到目标节点的前一个节点
    struct ListNode* prev = head;
    for (int i = 0; i < target - 1; i++) {
        prev = prev->next;  // 移动到目标节点的前一个节点
    }

    // 5. 删除目标节点
    struct ListNode* temp = prev->next;  // 目标节点
    prev->next = temp->next;            // 跳过目标节点,重新连接链表
    free(temp);                         // 释放目标节点的内存

    // 6. 返回删除后的链表头节点
    return head;
}

标签:head,ListNode,19,next,链表,int,节点,倒数第
From: https://www.cnblogs.com/zeta186012/p/18412217

相关文章

  • django特定地区冷链物流信息调度系统-计算机毕业设计源码92919
    特定地区冷链物流信息调度系统研究与应用摘要本研究针对特定地区的冷链物流信息调度系统进行了深入探索与实践。冷链物流作为一种特殊的物流方式,对于保障食品、药品等易腐产品的新鲜度和质量至关重要。然而,在特定地区,由于地理环境、经济水平和物流资源的限制,冷链物流面临着......
  • 3、静态链表
    1、静态链表初始化head指向-1代表当前为空链表,pool指向下一个可用空间(在数组下标为2的空间),2指向3,3指向4,最后的指向0表示没有下一个节点,以此链接起来。2、实现代码#include<stdio.h>#include<malloc.h>#defineMAX_SIZE20typedefcharElemType;typedefstructS......
  • 【Canvas与密铺】90年代马赛克密铺效果 1920x1080
    【成图】【代码】<!DOCTYPEhtml><htmllang="utf-8"><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><head><title>20世纪90年代马赛克瓷砖效果1920x1080</title><styletype=&quo......
  • 用Python实现时间序列模型实战——Day 19: 时间序列中的异常检测与处理
    一、学习内容1.时间序列中的异常检测方法在时间序列分析中,异常检测是识别时间序列中不同于正常行为的点。这些异常点可能是由于数据记录错误、极端事件或系统故障引起的,常见的异常检测方法包括:基于统计的方法:Z-score:计算每个数据点与其均值的标准差距离,判断其是否为异常......
  • [极客大挑战 2019]BabySQL
    启动靶机熟悉的界面测试发现or被过滤且输入#号无法起到注释作用猜测本靶机考点过滤查询关键词语句or,union,select,and,by和注释符#测试后查询关键词发现过滤只是单次过滤可以使用aandnd,oorr,uunionnion等绕过过滤而#则可以用urlencode编码格式变成%23绕过,接下来我们进行......
  • 22319 Business Analysis (Capstone)
    22319 BusinessAnalysis(Capstone)Spring2024SubjectdescriptionTheaimofthissubject istodemonstrateand apply a framework for business analysis and valuation using both    financialandnon-financialdata.Theemphasisofthesubject......
  • 链表
    1、创建链表-无头结点#include<stdio.h>#include<malloc.h>#include<assert.h>typedefintElemType;//定义链表typedefstructListNode{ElemTypedata;structListNode*next;}ListNode;typedefListNode*PList;//初始化链表,让链表一开始指向为空v......
  • 华为OD机试真题-寻找链表的中间节点-2024年OD统一考试(E卷)
    最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客   题目描述给定一个单链表QL,请编写程序输出L中间结点保存的数据,如果有两个中间结点,则输出第二个中间结点保存的数据。例如:给定L为1→7→5,则输出应该为7,给定L为1→2→3→4,则输......
  • C语言----使用链表实现的客户管理系统
    实现一个客户信息管理系统,功能包括添加客户、修改客户、删除客户、显示客户列表。学完了C语言和链表没事情干拿出来写一写,检测下学习成果#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstructNode{intnum;charname[20];chargender;......
  • [极客大挑战 2019]LoveSQL 1
    启动靶机作者不建议使用sqlmap我们这里就进行手工注入用万能口令登录admin'or1=1#,详情见上文(https://www.cnblogs.com/m1saka1/p/18411197)登录成功获得用户名和密码,发现密码并没有卵用,只能换思路利用账号密码的回显页面进行sql注入爆破数据库由于网站自动转义,为了方......