day03 移除链表元素 设计链表 反转链表

题目1:203 移除链表元素

题目链接:203 移除链表

题意

删除链表中所有满足Node.val==val的节点   返回新的头节点

注意使用cur临时指针,遍历链表,这样才可以最终返回head,不可以拿着head去遍历,否则,头节点会改变,无法返回整个链表

分类讨论

代码

/*** 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* removeElements(ListNode* head, int val) {//删除头节点while(head!=NULL && head->val==val){ListNode *tmp = head;//定义一个节点变量,用于释放内存head = head->next;delete tmp;//手动释放内存}//删除非头节点 (遍历所有节点)ListNode *cur = head;while(cur!=NULL && cur->next!=NULL){if(cur->next->val==val){ListNode *tmp = cur->next;//定义一个节点变量,用于释放内存cur->next = cur->next->next;delete tmp;//手动释放内存}else{cur = cur->next;} }return head;}
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

虚拟头节点

本题使用虚拟头节点方法  更优,这样不用分类讨论,可以统一操作

代码

/*** 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* removeElements(ListNode* head, int val) {//定义虚拟头节点ListNode *dummyhead = new ListNode(0);dummyhead->next = head;//定义临时指针cur,遍历链表ListNode *cur = dummyhead;//遍历所有的链表节点while(cur!=NULL && cur->next!=NULL){if(cur->next->val==val){ListNode *tmp = cur->next;//定义节点变量,用于释放内存cur->next = cur->next->next;delete tmp;     //手动释放内存}else{cur = cur->next;}}return dummyhead->next;//注意返回的dummyhead一定是新链表的头节点}
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

题目2:707 设计链表

题目链接:707 设计链表

题意

链表实现如下功能:

①初始化节点

②获取链表的某个节点值  (index从0开始,head的index为0)

③在头节点前面插入一个节点

④在尾节点后面插入一个节点

⑤在第n个节点处插入一个节点

⑥删除第n个节点

代码

①初始化节点

//定义链表节点结构体struct LinkedNode {int val;LinkedNode* next;LinkedNode(int val):val(val),next(nullptr){}  //没有分号};//初始化链表MyLinkedList() {dummyhead = new LinkedNode(0);size_ = 0;   }

②获取链表的某个节点值  (index从0开始,head的index为0)

法1:cur指向dummyhead

代码1

int get(int index) {if(index<0 || index>(size_-1)) return -1;LinkedNode* cur = dummyhead;while(index){cur = cur->next;index--;}return cur->next->val;   }
法2:cur指向dummyhead->next

代码2

int get(int index) {if(index<0 || index>(size_-1)) return -1;LinkedNode* cur = dummyhead->next;while(index){cur = cur->next;index--;}return cur->val;   }

③在头节点前面插入一个节点

注意插入的节点顺序,这非常关键,这也是“坑”

代码

 void addAtHead(int val) {LinkedNode* newnode = new LinkedNode(val);newnode->next = dummyhead->next;dummyhead->next = newnode;size_ ++;//注意添加了元素,要在原链表的基础上加1}

④在尾节点后面插入一个节点

注意while循环的条件是cur->next!=NULL 不能是size_

代码

void addAtTail(int val) {LinkedNode* cur = dummyhead;LinkedNode* newnode = new LinkedNode(val);while(cur->next!=nullptr){cur = cur->next;}cur->next = newnode;size_++;//添加了元素,链表大小加1}

!!!错误代码(如果使用size_做循环操作,那么意味着表示链表大小的量size_会发生变化,不能拿代表真实的链表大小了)

void addAtTail(int val) {LinkedNode* cur = dummyhead;LinkedNode* newnode = new LinkedNode(val);while(size_){cur = cur->next;size_--;}cur->next = newnode;size_++;//添加了元素,链表大小加1}

如果想要使用这个量用于while循环的条件判定,可以将size_赋值给一个新变量n,代码如下,这时,代码就是正确的了

void addAtTail(int val) {int n = size_;LinkedNode* cur = dummyhead;LinkedNode* newnode = new LinkedNode(val);while(n){cur = cur->next;n--;}cur->next = newnode;size_++;//添加了元素,链表大小加1}

⑤在第n个节点处插入一个节点

注意“坑”       :即顺序  

在第n个节点处插入一个节点,因此一定要知道第n-1个节点,所以cur=dummyhead

代码

void addAtIndex(int index, int val) {if(index>size_) return;if(index<0) index = 0;LinkedNode* newnode = new LinkedNode(val);LinkedNode* cur = dummyhead;while(index){cur = cur->next;index--;}newnode->next = cur->next;cur->next = newnode;size_++;//新加入了节点,链表大小要加1}

⑥删除第n个节点

删除第n个节点,一定要知道第n-1个节点,因此,cur=dummyhead

代码

void deleteAtIndex(int index) {if(index>(size_-1)||index<0) return;LinkedNode* cur = dummyhead;while(index){cur = cur->next;index--;}//注意释放内存LinkedNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;tmp = nullptr;size_--;//删除了一个元素,链表大小减1}

整体代码

class MyLinkedList {
public:
//定义链表节点结构体struct LinkedNode {int val;LinkedNode* next;LinkedNode(int val):val(val),next(nullptr){}  //没有分号};//初始化链表MyLinkedList() {dummyhead = new LinkedNode(0);size_ = 0;   }int get(int index) {if(index<0 || index>(size_-1)) return -1;LinkedNode* cur = dummyhead;while(index){cur = cur->next;index--;}return cur->next->val;   }void addAtHead(int val) {LinkedNode* newnode = new LinkedNode(val);newnode->next = dummyhead->next;dummyhead->next = newnode;size_ ++;//注意添加了元素,要在原链表的基础上加1}void addAtTail(int val) {LinkedNode* cur = dummyhead;LinkedNode* newnode = new LinkedNode(val);while(cur->next!=nullptr){cur = cur->next;}cur->next = newnode;size_++;//添加了元素,链表大小加1}void addAtIndex(int index, int val) {if(index>size_) return;if(index<0) index = 0;LinkedNode* newnode = new LinkedNode(val);LinkedNode* cur = dummyhead;while(index){cur = cur->next;index--;}newnode->next = cur->next;cur->next = newnode;size_++;//新加入了节点,链表大小要加1}void deleteAtIndex(int index) {if(index>(size_-1)||index<0) return;LinkedNode* cur = dummyhead;while(index){cur = cur->next;index--;}//注意释放内存LinkedNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;tmp = nullptr;size_--;//删除了一个元素,链表大小减1}void printLinkedList() {LinkedNode* cur = dummyhead;while(cur->next!=nullptr){cout<<cur->next->val<<" ";cur = cur->next;}cout<<endl;  }
private:int size_;LinkedNode* dummyhead;
};/*** 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);*/// 打印链表
  • 时间复杂度: 涉及 index 的相关操作为 O(index), 其余为 O(1)
  • 空间复杂度: O(n)  其中 n 为链表的长度。需要为每个节点分配内存空间来存储节点的值和下一个节点的指针,并且还需要一个额外的虚拟头节点指向链表的头部。

题目3:206 反转链表(面试高频)

题目链接:206 反转链表

题意

根据链表的头节点head  返回反转后的链表

双指针

代码

/*** 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* reverseList(ListNode* head) {ListNode* pre = NULL;ListNode* cur = head;while(cur!=NULL){ListNode* temp = cur->next;cur->next = pre;//pre,cur向后移动一位pre = cur;cur = temp;}return pre;}
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

递归

代码

/*** 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* reverse(ListNode* cur, ListNode* pre){//终止条件if(cur==NULL) return pre;//单层递归逻辑ListNode* temp = cur->next;cur->next = pre;return reverse(temp,cur);}ListNode* reverseList(ListNode* head) {return reverse(head,NULL);}
};
  • 时间复杂度: O(n), 要递归处理链表的每个节点
  • 空间复杂度: O(n), 递归调用了 n 层栈空间

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ant Design Vue 编译后的网页特点是什么,怎么确认他是用的前端 Ant Design Vue 技术栈的呢?

Ant Design Vue 是一个前端 UI 框架&#xff0c;使用 Vue.js 构建。它包含了大量的预设样式和组件&#xff0c;如按钮、表单、表格等&#xff0c;可以帮助开发者快速构建出优雅且功能丰富的网页。但是&#xff0c;要确定一个编译后的网页是否使用了 Ant Design Vue&#xff0c;…

lunux(mysql下载以及操作)

下载mysql 查看镜像 docker images 下载MySQL镜像 mysql/mysql-server:8.0 创建文件夹&#xff0c;创建配置文件和放数据文件 mkdir -p /data/mysql/{conf,,data} 创建配置文件 my.cnf 写入配置文件my.cnf的代码 [client] default-character-setutf8[mysql] de…

MySQL四大引擎,数据库管理,数据表管理,数据库账号管理

MySQL四大引擎 InnoDB InnoDB引擎是MySQL默认的存储引擎。它支持事务和行级锁定&#xff0c;并具有高并发性和数据完整性保护的特性。InnoDB适用于具有复杂查询和高并发读写操作的应用程序。MyISAM InnoDB引擎特点和优势 事务支持&#xff1a;InnoDB支持ACID&#xff08;原子…

css文本溢出处理——单行、多行

日常开发中&#xff0c;经常会遇到需要展示的文本过长&#xff0c;这种情况下&#xff0c;为了提高用户的使用体验&#xff0c;最常见的处理方式就是把溢出的文本显示成省略号。 处理文本的溢出的方式&#xff1a;1&#xff09;单行文本溢出&#xff1b; 2&#xff09;多行文本…

快速打通 Vue 3(三):Vue3 中的 watch 监听器与新特性

很激动进入了 Vue 3 的学习&#xff0c;作为一个已经上线了三年多的框架&#xff0c;很多项目都开始使用 Vue 3 来编写了 这一组文章主要聚焦于 Vue 3 的新技术和新特性 如果想要学习基础的 Vue 语法可以看我专栏中的其他博客 Vue&#xff08;一&#xff09;&#xff1a;Vue 入…

《低功耗方法学》翻译——卷首语

就目前半导体的发展现状来说&#xff0c;我们国家还处在奋力追赶阶段。在我国半导体行业历经多轮技术制裁的今天&#xff0c;我们不得不承认的是&#xff0c;半导体技术最先进的就是美国。我国早在上世纪六七十年代就有涉足半导体技术&#xff0c;大量华裔留美的爱国人士回国为…

清风数学建模笔记-因子分析

内容&#xff1a;因子分析 概念&#xff1a; 通过分析研究变量间的相关系数矩阵&#xff0c;把这些变量间错综复杂的关系归结成少数几个综合因子&#xff0c;由于归结出的因子个数少于原始变量的个数&#xff0c;但是又包含原始变量的信息&#xff0c;所以这一过程也称之为降…

Django Web框架

1、创建PyCharm项目 2、安装框架 pip install django4.2.0 3、查看安装的包列表 4、使用命令创建django项目 django-admin startproject web 5、目录结构 6、运行 cd web python manage.py runserver7、初始化后台登录的用户名密码 执行数据库迁移生成数据表 python man…

Objects are not valid as a React child (found: object with keys {name}).

在jsx中可以嵌套表达式&#xff0c;将表达式作为内容的一部分&#xff0c;但是要注意&#xff0c;普通对象不能作为子元素&#xff1b;但是数组&#xff0c;react元素对象是可以的 如下&#xff1a;不能将stu这个对象作为子元素放 function App() {const myCal imgStyleconst…

sentinel控制面板dashboard的下载安装教程

目录 一、dashboard控制面板下载二、启动dashboard 一、dashboard控制面板下载 资源下载地址: https://github.com/alibaba/Sentinel/releases 也可以点击这里进行下载&#xff0c;无需积分 找到需要下载的版本&#xff0c;展开下面的资源Assets&#xff0c;下载sentinel-das…

NSSCTF Http pro max plus

开启环境: 进去显示只允许本地访问,打开bp: 请求头写 x-forwarded-for: 127.0.0.1 换一种 client-ip: 127.0.0.1 执行显示 You are not from pornhub.com ! 请求头写 referer: pornhub.com 执行显示 不开代理你想上p站&#xff1f; 代理服务器地址是Clash.win ,请求头写 via: …

手把手教你学会接口自动化框架的搭建-前言

在网上看过很多帖子,各种接口自动化的框架眼花缭乱,但是对于很多才做自动化的新手,那是一头雾水。 因此,我决定出一个系列,让你能够按照我的文档一步步把接口自动化都做起来,而不是网上这种一股脑的全部抛出,让你看的云里雾里的。 看完这些文档保证你能去任何一家公司,…