【leetcode题解C++】707.设计链表 and 19.删除链表的倒数第N个结点

news2025/2/24 11:01:25

707.设计链表

你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

实现 MyLinkedList 类:

  • MyLinkedList() 初始化 MyLinkedList 对象。
  • int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
  • void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
  • void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
  • void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
  • void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

示例:

输入
["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
[[], [1], [3], [1, 2], [1], [1], [1]]
输出
[null, null, null, null, 2, null, 3]

解释
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1, 2);    // 链表变为 1->2->3
myLinkedList.get(1);              // 返回 2
myLinkedList.deleteAtIndex(1);    // 现在,链表变为 1->3
myLinkedList.get(1);              // 返回 3

思路:设计一个单链表,在按索引添加节点时要加以注意。

代码实现:

class MyLinkedList {
public:
    typedef struct LinkNode {
        int val;
        struct LinkNode *next;
        LinkNode(int val):val(val), next(nullptr) {}
    }LinkNode;

    MyLinkedList() {
        head = new LinkNode(0);
        size = 0;
    }
    
    int get(int index) {
        if(index < 0 || index > (size - 1)) {
            return -1;
        }     
        LinkNode *p = head->next;   
        while(index--) {
            p = p->next;
        }
        return p->val;
    }
    
    void addAtHead(int val) {
        LinkNode *p = new LinkNode(val);
        p->next = head->next;
        head->next = p;
        ++size;
    }
    
    void addAtTail(int val) {
        LinkNode *p = new LinkNode(val);
        LinkNode *s = head;
        while(s->next != nullptr) {
            s = s->next;
        }
        s->next = p; 
        ++size;
    }
    
    void addAtIndex(int index, int val) {
        if(index > size) return;
        LinkNode *p = new LinkNode(val);
        LinkNode *s = head;
        if(0 <= index && index <= size) {
            while(index--) {
                s = s->next;
            }
            p->next = s->next;
            s->next = p;
        }
        ++size;
    }
    
    void deleteAtIndex(int index) {
        if (index >= size || index < 0) return;
        LinkNode* s = head;
        while(index--) {
            s = s->next;
        }
        LinkNode* tmp = s->next;
        s->next = s->next->next;
        delete tmp;
        tmp = nullptr;
        --size;
    }
private:
    LinkNode *head;
    int size;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

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]

 思路:创建一个新的带头结点的链表,用一个指针管理旧链表,一个指针用来往新的链表添加结点,一个整型变量来记录旧链表长度(方便推算出倒数第N个结点到底是哪个),新链表一直添加到被删除结点之前,然后跳过被删除结点。

代码实现:

/**
 * 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 *newList = new ListNode();
        newList->next = head;
        ListNode *p = head;
        ListNode *q = newList;
        int len = 0;
        while(p != nullptr) {
            ++len;
            p = p->next;
        }
        for(int i = 0; i < len-n; i++) {
            q = q->next;
        }
        q->next = q->next->next;
        return newList->next;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1391565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过ssh链接到群晖后台操作洗白

本篇适合二合一系统因各种原因不想进PE修改的 洗白进阶操作&#xff0c;需要对Linux的命令有基本的了解&#xff0c;如果完全不懂&#xff0c;建议不要按此方法操作&#xff0c;请看常规流程&#xff01; 群晖洗白引导修复所用工具 请先提前下载解压缩好 下载地址https://ww…

数据库视图索引练习

学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;SC (Sno, Cno, Score)…

Android 12.0 framework层实现app默认全屏显示

1.前言 在12.0的系统rom定制化开发中,在对于第三方app全屏显示的功能需求开发中,需要默认app全屏显示,针对这一个要求,就需要在系统启动app的过程中,在绘制app阶段就设置全屏属性,接下来就实现这个功能 效果图如下: 2.framework层实现app默认全屏显示的核心类 framewor…

C# wpf 获取控件刷新的时机

文章目录 前言一、为何要获取刷新时机&#xff1f;例子一、隐藏控件后截屏例子二、修改控件大小后做计算 二、如何实现&#xff1f;1.使用动画2.使用TaskCompletionSource 三、完整代码四、使用示例1、隐藏工具条截屏2、修改宽高后获取ActualWidth、ActualHeight 总结 前言 做…

LV.13 D10 Linux内核移植 学习笔记

具体实验步骤在lv13day10 实验十 一、Linux内核概述 1.1 内核与操作系统 内核 内核是一个操作系统的核心&#xff0c;提供了操作系统最基本的功能&#xff0c;是操作系统工作的基础&#xff0c;决定着整个系统的性能和稳定性 操作系统 操作系统是在内核的基础上添…

牛客-寻找第K大、LeetCode215. 数组中的第K个最大元素【中等】

文章目录 前言牛客-寻找第K大、LeetCode215. 数组中的第K个最大元素【中等】题目及类型思路思路1&#xff1a;大顶堆思路2&#xff1a;快排二分随机基准点 前言 博主所有博客文件目录索引&#xff1a;博客目录索引(持续更新) 牛客-寻找第K大、LeetCode215. 数组中的第K个最大元…

Spark SQL函数定义

目录 窗口函数 SQL函数分类 Spark原生自定义UDF函数 Pandas的UDF函数 Apache Arrow框架基本介绍 基于Arrow完成Pandas DataFrame和Spark DataFrame互转 基于Pandas完成UDF函数 自定义UDF函数 自定义UDAF函数 窗口函数 分析函数 over(partition by xxx order by xxx [as…

opencv_角点检测

文章内容 一个opencv检测角点的程序 运行效果 #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream>using namespace cv; using namespace std;void detectCorners(M…

定制键盘设计

方案1 stm32方案 参考 智辉君的键盘 方案2 沁恒方案 CH9328与ch9329区别&#xff1a;一个是单向&#xff0c;一个是双向。 ch9329是ch9328的升级款。 原理篇4、CH9328使用-CSDN博客https://blog.csdn.net/qq_44817843/article/details/112124822

服务器推送数据你还在用 WebSocket么?

当涉及到推送数据时,人们首先会想到 WebSocket。 的确,WebSocket 允许双向通信,可以自然地用于服务器到浏览器的消息推送。 然而,如果只需要单向的消息推送,HTTP 通过服务器发送的事件也有这种功能。 WebSocket 的通信过程如下: 首先,通过 HTTP 切换协议。服务器返回 101 状…

Shell脚本同时调用#!/bin/bash和#!/usr/bin/expect

如果你想在一个脚本中同时使用bash和expect&#xff0c;你可以将expect部分嵌入到bash脚本中。以下是一个示例&#xff1a; #!/bin/bash# 设置MySQL服务器地址、端口、用户名和密码 MYSQL_HOST"localhost" MYSQL_PORT"3306" MYSQL_USER"your_usernam…

Shiro漏洞

VULHUB部署环境 下载vulhub https://github.com/vulhub/vulhub/archive/master.zip?spma2c6h.12873639.article-detail.7.76036a98Plc8q5&filemaster.zip 进入漏洞文件夹直接部署 界面 漏洞 如果勾选记住账号&#xff0c;请求包会附带remember-me字段&#xff0c;服务…

转行做鸿蒙开发首先需要学习哪些?

随着越来越多的企业和团队开始布局鸿蒙生态&#xff0c;鸿蒙开发人才的需求也呈现出井喷式的增长。对于开发者而言&#xff0c;掌握鸿蒙开发技能不仅意味着能够抓住这个千载难逢的机遇&#xff0c;更意味着能够在未来的科技竞争中占据先机。 在这个变革的时代&#xff0c;鸿蒙开…

数据结构与算法:归并排序

数据结构与算法&#xff1a;归并排序 归并思想递归法非递归 归并思想 在讲解归并排序前&#xff0c;我们先看到一个问题&#xff1a; 对于这样两个有序的数组&#xff0c;如何将它们合并为一个有序的数组&#xff1f; 在此我们处理这个问题的思路就是&#xff1a;开辟一个新的…

码云星辰:未来运维的技术交响曲

&#x1f6a9;本文介绍 ​ 随着信息技术的迅猛发展&#xff0c;运维领域正经历着翻天覆地的变革。未来的运维工程师将需要拥有更广泛、更深入的技能&#xff0c;以适应日益复杂和多变的系统环境。本文将深入探讨运维未来的行业发展趋势&#xff0c;并详细分析需要掌握的关键技…

java web万能模板(附带防微博源码)

文章目录 java EE 项目万能模板套用创建一个java EE项目1.点击java ee2.点击finish3.一个Java ee项目创建完毕4.点击运行5.运行结果 万能模板连接数据库1.在pom.xml文件导入数据库连接所需要的依赖2.进行导入3. 导入以后刷新Maven4.找到 resources 文件。5.在resources的文件路…

【论文阅读笔记】4篇Disentangled representation learning用于图像分割的论文

4篇应用解耦表示学习的文章&#xff0c;这里只关注如何解耦&#xff0c;更多细节不关注&#xff0c;简单记录一下。 1.Robust Multimodal Brain Tumor Segmentation via Feature Disentanglement and Gated Fusion Chen C, Dou Q, Jin Y, et al. Robust multimodal brain tum…

trucksim与simulink联合仿真基于pid控制算法实现车道保持

一、pid算法原理不做过多解释自行百度&#xff0c;这里采用的是位置式pid。 效果视频&#xff1a;https://www.bilibili.com/video/BV1CN4y1p7gb/?vd_sourcea1425ad8eaf3586e891a6d0040eb89cc 二、trucksim界面操作截图 三、simulink模型截图 采用的P &#xff1b; I和…

NG+WAF实现应用安全访问

一、基本概念 什么是waf&#xff1f; Web应用防火墙&#xff08;waf&#xff09;是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品&#xff0c;WAF是一种工作在应用层的、通过特定的安全策略来专门为Web应用提供安全防护的产品。 什么是ngx_lua_…

SparkSQL——DataFrame

DataFrame Dataframe 是什么 DataFrame 是 SparkSQL中一个表示关系型数据库中 表的函数式抽象, 其作用是让 Spark处理大规模结构化数据的时候更加容易. 一般 DataFrame可以处理结构化的数据, 或者是半结构化的数据, 因为这两类数据中都可以获取到 Schema信息. 也就是说 DataFra…