代码随想录笔记--链表篇

目录

1--虚拟头节点的使用

2--设计链表

3--反转链表

4--两两交换链表中的节点

5--快慢指针

5-1--删除链表倒数第N个节点

5-2--环形链表

5-3--环形链表II


1--虚拟头节点的使用

        在链表相关题目中,常新定义一个虚拟头结点 dummynode 来指向原链表的头结点,当需要返回链表时,只需返回 dummynode->next;

#include <iostream>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) {if(head==nullptr) return head;ListNode* dummynode = new ListNode(); // 新建虚拟头结点dummynode->next = head;ListNode* cur = dummynode;while(cur->next != nullptr){if(cur->next->val == val){ListNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;tmp = nullptr;}else{cur = cur->next;}}return dummynode->next;}
};int main(int arc, char *argv[]){ListNode* Node1 = new ListNode(1);ListNode* Node2 = new ListNode(2);ListNode* Node3 = new ListNode(6);ListNode* Node4 = new ListNode(3);ListNode* Node5 = new ListNode(4);ListNode* Node6 = new ListNode(5);ListNode* Node7 = new ListNode(6);Node1->next = Node2;Node2->next = Node3;Node3->next = Node4;Node4->next = Node5;Node5->next = Node6;Node6->next = Node7;Solution S1;int val = 6;ListNode* res = S1.removeElements(Node1, val);ListNode* cur = res;while(cur != NULL){std::cout << cur->val << " ";cur = cur->next;}return 0;
}

2--设计链表

#include <iostream>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 > (_size - 1) || index < 0) { // 不合法indexreturn -1;}LinkedNode* cur = _dummyHead->next;while(index--){cur = cur->next;}return cur->val;}void addAtHead(int val) {LinkedNode* newNode = new LinkedNode(val);newNode->next = _dummyHead->next;_dummyHead->next = newNode;_size++;}void addAtTail(int val) {LinkedNode* newNode = new LinkedNode(val);LinkedNode* cur = _dummyHead;while(cur->next != nullptr){cur = cur->next;}cur->next = newNode;_size++;}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;}newNode->next = cur->next;cur->next = newNode;_size++;}void deleteAtIndex(int index) {if (index >= _size || index < 0) {return;}LinkedNode* cur = _dummyHead;while(index--) {cur = cur ->next;}LinkedNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;tmp=nullptr;_size--;}// 打印链表void printLinkedList() {LinkedNode* cur = _dummyHead;while (cur->next != nullptr) {std::cout << cur->next->val << " ";cur = cur->next;}std::cout << std::endl;}
private:int _size;LinkedNode* _dummyHead;};int main(int arc, char *argv[]){MyLinkedList myLinkedList;myLinkedList.addAtHead(1);myLinkedList.addAtTail(3);myLinkedList.addAtIndex(1, 2);    // 链表变为 1->2->3std::cout << myLinkedList.get(1) << std::endl;  // 返回 2myLinkedList.deleteAtIndex(1);    // 现在,链表变为 1->3std::cout << myLinkedList.get(1) << std::endl;  // 返回 3return 0;
}

3--反转链表

双指针解法: 

#include <iostream>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){if(head == nullptr) return head;ListNode *pre = nullptr;ListNode *cur = head;while(cur != NULL){ListNode *tmp = cur->next;cur->next = pre;pre = cur;cur = tmp;}return pre;}
};int main(int arc, char *argv[]){ListNode *Node1 = new ListNode(1);ListNode *Node2 = new ListNode(2);ListNode *Node3 = new ListNode(3);ListNode *Node4 = new ListNode(4);ListNode *Node5 = new ListNode(5);Node1->next = Node2;Node2->next = Node3;Node3->next = Node4;Node4->next = Node5;Solution S1;ListNode *res = S1.reverseList(Node1);ListNode *cur = res;while(cur != NULL){std::cout << cur->val << " ";cur = cur->next;}return 0;
}

递归写法:

#include <iostream>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){if(head == nullptr) return head;return reverse(head, nullptr);}ListNode* reverse(ListNode* cur, ListNode* pre){if(cur == nullptr) return pre;ListNode *tmp = cur->next;cur->next = pre;return reverse(tmp, cur);}
};int main(int arc, char *argv[]){ListNode *Node1 = new ListNode(1);ListNode *Node2 = new ListNode(2);ListNode *Node3 = new ListNode(3);ListNode *Node4 = new ListNode(4);ListNode *Node5 = new ListNode(5);Node1->next = Node2;Node2->next = Node3;Node3->next = Node4;Node4->next = Node5;Solution S1;ListNode *res = S1.reverseList(Node1);ListNode *cur = res;while(cur != NULL){std::cout << cur->val << " ";cur = cur->next;}return 0;
}

4--两两交换链表中的节点

#include <iostream>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* swapPairs(ListNode* head) {if(head == nullptr) return head;ListNode *dummyNode = new ListNode();dummyNode->next = head;ListNode *cur = dummyNode;while(cur->next != nullptr && cur->next->next != nullptr){ListNode *tmp1 = cur->next;ListNode *tmp2 = cur->next->next->next;cur->next = cur->next->next;cur->next->next = tmp1;tmp1->next = tmp2;cur = cur->next->next;}return dummyNode->next;}
};int main(int arc, char *argv[]){ListNode *Node1 = new ListNode(1);ListNode *Node2 = new ListNode(2);ListNode *Node3 = new ListNode(3);ListNode *Node4 = new ListNode(4);Node1->next = Node2;Node2->next = Node3;Node3->next = Node4;Solution S1;ListNode *res = S1.swapPairs(Node1);ListNode *cur = res;while(cur != NULL){std::cout << cur->val << " ";cur = cur->next;}return 0;
}

5--快慢指针

5-1--删除链表倒数第N个节点

快慢指针

#include <iostream>
#include <vector>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 *dummyNode = new ListNode();dummyNode->next = head;ListNode* slow = dummyNode;ListNode* fast = dummyNode;while(n-- && fast != NULL){fast = fast->next;}while(fast->next != NULL){slow = slow->next;fast = fast->next;}ListNode *target = slow->next;slow->next = target->next;delete target;target = nullptr;return dummyNode->next;}
};int main(int argc, char argv[]){ListNode *Node1 = new ListNode(1);ListNode *Node2 = new ListNode(2);ListNode *Node3 = new ListNode(3);ListNode *Node4 = new ListNode(4);ListNode *Node5 = new ListNode(5);Node1->next = Node2;Node2->next = Node3;Node3->next = Node4;Node4->next = Node5;int n = 2;Solution S1;ListNode *res = S1.removeNthFromEnd(Node1, n);ListNode *cur = res;while(cur != NULL){std::cout << cur->val << " ";cur = cur->next;}return 0;
}

5-2--环形链表

快慢指针,当链表有环时,快慢指针必定相遇;

#include <iostream>
#include <vector>struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};class Solution {
public:bool hasCycle(ListNode *head) {if(head == nullptr) return false;ListNode *slow = head;ListNode *fast = head;while(fast != NULL && fast->next != NULL){fast = fast->next->next;slow = slow->next;if(slow == fast) break;}if(fast == NULL || fast->next == NULL) return false;else return true;}
};int main(int argc, char argv[]){ListNode *Node1 = new ListNode(1);ListNode *Node2 = new ListNode(2);ListNode *Node3 = new ListNode(0);ListNode *Node4 = new ListNode(-4);Node1->next = Node2;Node2->next = Node3;Node3->next = Node4;Node4->next = Node2;Solution S1;bool res = S1.hasCycle(Node1);if(res) std::cout << "true" << std::endl;else std::cout << "false" << std::endl;return 0;
}

5-3--环形链表II

        快慢指针,快指针每次走两步,慢指针每次走一步,根据快慢指针是否相遇判断是否有环;

        当快慢指针第一次相遇后,慢指针从头出发,快指针从第一次相遇的节点出发,快慢指针均每次走一步,当下一次相遇时就处于环的入口节点,返回即可;

#include <iostream>
#include <vector>struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};class Solution {
public:ListNode *detectCycle(ListNode *head) {if(head == nullptr) return head;ListNode *slow = head;ListNode *fast = head;while(fast != NULL && fast->next != NULL){fast = fast->next->next;slow = slow->next;if(fast == slow) break; // 第一次相遇}if(fast == NULL || fast->next == NULL) return NULL; // 没有环// 从头开始走slow = head;while(slow != fast){slow = slow->next;fast = fast->next;}// 第二次相遇就是环的入口return slow;}
};int main(int argc, char argv[]){ListNode *Node1 = new ListNode(1);ListNode *Node2 = new ListNode(2);ListNode *Node3 = new ListNode(0);ListNode *Node4 = new ListNode(-4);Node1->next = Node2;Node2->next = Node3;Node3->next = Node4;Node4->next = Node2;Solution S1;ListNode * res = S1.detectCycle(Node1);std::cout << res->val << std::endl;return 0;
}

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

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

相关文章

文本编辑器Vim常用操作和技巧

文章目录 1. Vim常用操作1.1 Vim简介1.2 Vim工作模式1.3 插入命令1.4 定位命令1.5 删除命令1.6 复制和剪切命令1.7 替换和取消命令1.8 搜索和搜索替换命令1.9 保存和退出命令 2. Vim使用技巧 1. Vim常用操作 1.1 Vim简介 Vim是一个功能强大的全屏幕文本编辑器&#xff0c;是L…

谷歌发布Gemini以5倍速击败GPT-4

在Covid疫情爆发之前&#xff0c;谷歌发布了MEENA模型&#xff0c;短时间内成为世界上最好的大型语言模型。谷歌发布的博客和论文非常可爱&#xff0c;因为它特别与OpenAI进行了比较。 相比于现有的最先进生成模型OpenAI GPT-2&#xff0c;MEENA的模型容量增加了1.7倍&#xf…

Java 数据结构使用学习

Set和List的区别 Set 接口实例存储的是无序的&#xff0c;不重复的数据。List 接口实例存储的是有序的&#xff0c;可以重复的元素。 Set 检索效率低下&#xff0c;删除和插入效率高&#xff0c;插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。 List 和数…

【LeetCode算法系列题解】第6~10题

CONTENTS LeetCode 6. N 字形变换&#xff08;中等&#xff09;LeetCode 7. 整数反转&#xff08;中等&#xff09;LeetCode 8. 字符串转换整数-atoi&#xff08;中等&#xff09;LeetCode 9. 回文数&#xff08;简单&#xff09;LeetCode 10. 正则表达式匹配&#xff08;困难&…

C# Linq源码分析之Take(四)

概要 本文主要对Take的优化方法进行源码分析&#xff0c;分析Take在配合Select&#xff0c;Where等常用的Linq扩展方法使用时候&#xff0c;如何实现优化处理。 本文涉及到Select, Where和Take和三个方法的源码分析&#xff0c;其中Select, Where, Take更详尽的源码分析&…

【日积月累】后端刷题日志

刷题日志 说说对Java的理解JAVA中抽象类和接口之间的区别Java中的泛型 和equals()的区别八种基本数据类型与他们的包装类在一个静态方法内调用一个非静态成员为什么是非法的静态方法与实例方法有何不同重载与重写深拷贝浅拷贝面向过程与面向对象成员变量与局部变量Spring框架Sp…

Spring Bean对象生命周期

文章目录 前言基础通俗理解bean作用域 前言 最近学习spring的一些基础概念&#xff0c;所以就先了解了bean对象的概念&#xff0c;而且发现这个里面涉及到很多的内容&#xff0c;比如在spring中一个bean对象是如何创建以及销毁的这些概念&#xff0c;所以就打算总结一些spring…

微信开发之一键踢出群聊的技术实现

简要描述&#xff1a; 删除群成员 请求URL&#xff1a; http://域名地址/deleteChatRoomMember 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选…

SpringBoot之logback-spring.xml详细配置

《logback官网》 各种指导文件&#xff0c;有空自己去看&#xff0c;比如&#xff1a;我们需要调整的是布局&#xff0c;直接看Layouts。 pom.xml <!-- 环境配置 --><profiles><profile><id>dev</id><properties><spring.profiles.a…

基于java swing和mysql实现的汽车租赁管理系统(源码+数据库+文档+运行指导视频)

一、项目简介 本项目是一套基于java swing和mysql实现的汽车租赁管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经…

麒麟系统上安装 MySQL 8.0.24

我介绍一下在麒麟系统上安装 MySQL 8.0.24 的详细步骤&#xff0c;前提是您已经下载了 mysql-8.0.24-linux-glibc2.12-x86_64.tar.xz 安装包。其实安装很简单&#xff0c;但是有坑&#xff0c;而且问题非常严重&#xff01;由于麒麟系统相关文章博客较少&#xff0c;导致遇到了…

java八股文面试[数据库]——MySql聚簇索引和非聚簇索引区别

聚集索引和非聚集索引 聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致。 1、聚集索引 聚集索引表记录的排列顺序和索引的排列顺序一致&#xff08;以InnoDB聚集索引的主键索引来说&#xff0c;叶子节点中存储的就是行数据&#xff0c;行数据在…

MFC -- Date Time Picker 控件使用

当前环境&#xff1a;VS2015 Windows 10 //&#xff08;一&#xff09;使用普通函数&#xff0c; 获取当前时间CString strCurrentTime; COleDateTime m_time COleDateTime::GetCurrentTime(); strCurrentTime m_time.Format(_T("%Y-%m-%d %H:%M:%S")); SetDlgIt…

【python爬虫案例】用python爬豆瓣读书TOP250排行榜!

文章目录 一、爬虫对象-豆瓣读书TOP250二、python爬虫代码讲解三、讲解视频四、完整源码 一、爬虫对象-豆瓣读书TOP250 您好&#xff0c;我是 马哥python说 &#xff0c;一名10年程序猿。 今天我们分享一期python爬虫案例讲解。爬取对象是&#xff0c;豆瓣读书TOP250排行榜数…

使用这个插件,fiddler抓包直接生成httprunner脚本

har2case可以将.har文件转化成yaml格式或者json格式的httprunner的脚本文件&#xff0c;生成.har格式文件可以借助 fiddler 或 Charles 抓包工具 友情提示&#xff1a; 录制脚本&#xff0c;只是一个过渡&#xff0c;从0到1的一个过渡&#xff0c;如果让你直接写脚本&#xf…

xsschallenge通关(1-10)

文章目录 level1level 2level 3level 4level 5level 6level 7level 8level9level 10 level1 这一关很简单&#xff0c;标准的xss注入&#xff0c;打开hackbar&#xff0c;输入 <script>alert(/xss/)</script>点击EXECUTE&#xff0c;通关&#xff01; level 2 这…

设计模式之命令模式(Command)的C++实现

1、命令模式的提出 在软件开发过程中&#xff0c;“行为请求者”和“行为实现者”通常呈现一种“紧耦合”&#xff0c;如果行为的实现经常变化&#xff0c;则不利于代码的维护。命令模式可以将行为的请求者和行为的实现者进行解耦。具体流程是将行为请求者封装成一个对象&…

python基础爬虫反爬破解

文章目录 爬虫初识1. HTTP协议与WEB开发&#xff08;1&#xff09;简介&#xff08;2&#xff09;socket套接字&#xff08;3&#xff09;请求协议与响应协议 2. requests&反爬破解&#xff08;1&#xff09;UA反爬&#xff08;2&#xff09;referer反爬&#xff08;3&…

基于Java+SpringBoot+Vue前后端分离客户关系管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

电子词典dictionary

一、项目要求&#xff1a; 1.登录注册功能&#xff0c;不能重复登录&#xff0c;重复注册。用户信息也存储在数据库中。 2.单词查询功能 3.历史记录功能&#xff0c;存储单词&#xff0c;意思&#xff0c;以及查询时间&#xff0c;存储在数据库 4.基于TCP&#xff0c;支持多客户…