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

目录

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.hqwc.cn/news/92428.html

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

相关文章

今天面了一个来华为要求月薪25K,明显感觉他背了很多面试题...

最近有朋友去华为面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

Eclipse打jar包与JavaDOC文档的生成

补充知识点——Eclipse打jar包与JavaDOC文档的生成 1、Eclipse如何打jar包&#xff0c;如何运行jar包 Java当中编写的Java代码&#xff0c;Java类、方法、接口这些东西就是项目中相关内容&#xff0c;到时候我们需要把代码提供给甲方、或者是我们需要运行我们编写的代码&…

【Kali Linux高级渗透测试】深入剖析Kali Linux:高级渗透测试技术与实践

&#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于恒川的日常汇报系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏C语言初阶、C…

Spring源码分析(十)Bean实例化(下)

目录 1.1 循环依赖1.2 属性填充1.2.1 populateBean方法1.2.2 initializeBean方法执行Aware方法执行BeanPostProcessor后置处理器的前置处理方法执行初始化方法执行BeanPostProcessor后置处理器的后置处理方法&#xff1a;postProcessAfterInitialization()&#xff0c;允许对be…

数学建模:层次分析法

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 层次分析法 步骤描述 将问题条理化&#xff0c;层次化&#xff0c;构建出一个有层次的结构模型。层次分为三类&#xff1a;目标层&#xff0c;准则&#xff08;指标&#xff09;层&#xff0c;方案层。比…

高阶MySQL语句

数据准备 create table ky30 (id int,name varchar(10) primary key not null ,score decimal(5,2),address varchar(20),hobbid int(5)); insert into ky30 values(1,liuyi,80,beijing,2); insert into ky30 values(2,wangwu,90,shengzheng,2); insert into ky30 values(3,lis…

Nginx实现自签名SSL证书生成与配置

Nginx实现自签名SSL证书生成与配置 一、Nginx实现自签名SSL证书生成与配置1.名词介绍2.生成私钥3.生成公钥4.生成解密的私钥key5.签名生成证书6.配置证书并验证 二、总结 一、Nginx实现自签名SSL证书生成与配置 1.名词介绍 &#xff08;1&#xff09;key 私钥 明文–自己生成…

设计模式第八讲:常见重构技巧 - 去除多余的if else

设计模式第八讲&#xff1a;常见重构技巧 - 去除多余的if else 最为常见的是代码中使用很多的if/else&#xff0c;或者switch/case&#xff1b;如何重构呢&#xff1f;方法特别多&#xff0c;本文是设计模式第八讲&#xff0c;带你学习其中的技巧。 文章目录 设计模式第八讲&am…

阿里云centos9stream安装宝塔+vscode(code-server)集成云端开发环境

一、 安装宝塔面板 官网 https://www.bt.cn/new/download.htm 题外话&#xff1a;虽然感觉现在宝塔没以前好用了&#xff0c;而且有centos7、8 mysql编译导致OOM服务器挂掉无法ssh登录的情况&#xff0c;但他还是远程管理服务器的好选择&#xff0c;提示宝塔只支持最新的centos…

2023年高压快充行业研究报告

第一章 行业概况 1.1 行业定义 高压快充行业是指专注于为电动汽车、移动设备等提供高功率、高效率充电服务的行业。高压快充技术旨在通过采用更高的电压和更大的电流&#xff0c;缩短充电时间并提高充电效率。这种技术可以使电动汽车在短时间内充满电&#xff0c;从而提高其可…

Linux文件管理知识:查找文件(第二篇)

Linux文件管理知识:查找文件&#xff08;第二篇&#xff09; 上篇文章详细介绍了linux系统中查找文件的工具或者命令程序locate和find命令的基本操作。那么&#xff0c;今天这篇文章紧接着查找文件相关操作内容介绍。 Find命令所属操作列表中的条目&#xff0c;有助于我们想要…

DC/DC开关电源学习笔记(二)开关电源的分类

&#xff08;二&#xff09;开关电源的分类 1.DC/DC类开关电源2.AC/DC变换器3.电路结构分类4.功率开关管分类5.电路拓扑分类 根据变换方式&#xff0c;电源产品有下列四大类&#xff1b; &#xff08;1&#xff09;&#xff1a;第一大类&#xff1a;AC/DC开关电源&#xff1b; …