链表leetcode-1

目录

1.常用技巧

1.1引入虚拟头结点

1.2对于变量,不要太吝啬,可以多定义,方便处理

1.3快慢双指针

2.例题

 2.1两数相加

2.2两两交换链表中的节点

2.3重排链表

2.4合并K个升序链表

2.5K个一组翻转链表


1.常用技巧

1.1引入虚拟头结点

可以方便处理边界情况(因为有些题链表提供的是NULL,如果直接引用会报错,如果是循环链表,没有头结点,题目没有其他条件,就很难判断头尾)

方便对链表操作

1.2对于变量,不要太吝啬,可以多定义,方便处理

1.3快慢双指针

可以用于判环,找链表中环的入口,找链表中倒数第N个节点

关于这方面,可以看我这篇文章

链表(c语言版)-CSDN博客

链表的操作无非就是new一个新节点,尾插或头插,或中间插入,或删除。

头插常用于逆序链表

2.例题

 2.1两数相加

2. 两数相加 - 力扣(LeetCode)

这题是给的逆序,因为两数相加是从低位开始加,所以反而方便我们操作了。

只要做模拟即可。

利用一个虚拟头结点和尾指针,模拟加法。

下面是我看到题目马上就写出来的,看起来比较繁琐,但是思路比较清晰

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {int jw=0;ListNode*ans=new ListNode(-1);//头结点ListNode*tail=ans;//尾指针while(l1&&l2)//先处理两边都有数{int x=l1->val+l2->val;if(jw)x++,jw=0;if(x>=10)jw++,x-=10;ListNode *tmp=new ListNode(x);tail->next=tmp;tail=tmp;l1=l1->next;l2=l2->next;}while(l1)//处理单个{int x=l1->val;if(jw)x++,jw=0;if(x>=10)jw++,x-=10;ListNode *tmp=new ListNode(x);tail->next=tmp;tail=tmp;l1=l1->next;}while(l2)//处理单个{int x=l2->val;if(jw)x++,jw=0;if(x>=10)jw++,x-=10;ListNode *tmp=new ListNode(x);tail->next=tmp;tail=tmp;l2=l2->next;}while(jw)//处理多的进位{ListNode *tmp=new ListNode(1);tail->next=tmp;tail=tmp;jw--;}return ans->next;}
};

接下来这个版本是优化过,时间复杂度没区别,代码看起来比较简洁

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode*ans=new ListNode(-1);int x=0;ListNode*tail=ans;while(l1||l2||x){if(l1){x+=l1->val;l1=l1->next;}if(l2){x+=l2->val;l2=l2->next;}tail->next=new ListNode(x%10);x/=10;tail=tail->next;}tail=ans->next;delete ans;return tail;}
};

2.2两两交换链表中的节点

24. 两两交换链表中的节点 - 力扣(LeetCode)

下面的版本是我挺早写的

思路就是利用递归,比如第一个节点的时候,会把第三个节点开始交换后的头结点返回。

然后将第一个节点和第二个节点交换,并把原第一个节点的next指向上面返回的节点。

class Solution {
public:ListNode* swapPairs(ListNode* head) {if(head==nullptr||head->next==nullptr)return head;
//因为当前的一对,只有第一个是非NULL节点,第二个节点是NULL,或者第一个节点就是NULL。
//说明不能进行交换,直接返回第一个节点即可。ListNode*tmp=swapPairs(head->next->next);ListNode*ret=head->next;head->next->next=head;head->next=tmp;return  ret;}
};

接下来是迭代循坏的版本。稍显复杂


class Solution {
public:ListNode* swapPairs(ListNode* head) {if(head==nullptr||head->next==nullptr)return head;//可能只有1一个节点或没有节点ListNode *newhead=new ListNode(0);//虚拟头结点newhead->next=head;ListNode*prev=newhead;//前驱指针ListNode*cur=head;//当前指针ListNode*next=head->next;//当前的下一个指针ListNode*nnext=head->next->next;//当前的下一个的下一个指针while(cur&&next)//只要cur或next其中之一为空,就说明不用交换了。{prev->next=next;next->next=cur;cur->next=nnext;prev=cur;cur=nnext;if(cur)next=nnext->next;//注意原先的nnext可能为空if(next)nnext=next->next;//注意,原先的nnext的下一个指针可能为空}cur=newhead->next;delete newhead;return cur;}
};

2.3重排链表

143. 重排链表 - 力扣(LeetCode)

在写这题前,可以先写

876. 链表的中间结点 - 力扣(LeetCode)

206. 反转链表 - 力扣(LeetCode)

21. 合并两个有序链表 - 力扣(LeetCode)

链表(c语言版)-CSDN博客  这篇文章有反转和中间节点。

关于合并有序链表,可以参考合并有序数组,思路没区别

本题的一个思路,就是上面三题的结合


class Solution {
public:void reorderList(ListNode* head) {if(head==nullptr||head->next==nullptr)return;//考虑只有1个节点或没有节点//快慢指针查找中间节点ListNode*fast=head,*slow=head;ListNode*prev=nullptr;while(fast&&fast->next){prev=slow;slow=slow->next;fast=fast->next->next;}prev->next=nullptr;//注意断开链表起始位置和slow开始的部分//开始反转slow开始的部分ListNode*cur=slow,*next=slow->next,*newl2=nullptr,*newl1=head;prev=nullptr;while(cur){if(cur->next==nullptr)newl2=cur;cur->next=prev;prev=cur;cur=next;if(cur)next=next->next;}//开始合并两个有序链表ListNode*rethead=nullptr;ListNode*rettail=nullptr;ListNode*cur1=newl1,*cur2=newl2;while(cur1||cur2){if(cur1){if(rethead==nullptr){rethead=rettail=cur1;}else{rettail->next=cur1;rettail=rettail->next;}cur1=cur1->next;}if(cur2){if(rethead==nullptr){rethead=rettail=cur2;}else{rettail->next=cur2;rettail=rettail->next;}cur2=cur2->next;}}}
};

2.4合并K个升序链表

23. 合并 K 个升序链表 - 力扣(LeetCode)

本题有3个思路,第一个思路是暴力,我只在这文字描述,不写了,n^3复杂度,铁出事

暴力思路很简单,就是挑2个链表,进行合并两个有序链表的操作,然后把合并出来的链表,再跟剩下的其中一个链表继续重复操作。直到剩下链表都被合并进去了。

思路2,利用优先队列。假设有k个链表,平均n个节点,每次丢入优先队列都会经历一次log k的操作。所以复杂度O(nk log k)

class Solution {
public://重载下指针的比较,方便优先队列自动排序struct kp {bool operator()(const ListNode*l1,const ListNode*l2) const{return l1->val>l2->val;}};ListNode* mergeKLists(vector<ListNode*>& lists) {priority_queue<ListNode*, vector<ListNode*>, kp>q;int k = lists.size();//返回的链表头结点和尾节点ListNode* rethead = nullptr, *rettail = nullptr;//把链表数组的每个非空头结点放入队列。for(int i=0;i<k;i++){if(lists[i])q.push(lists[i]);}while (!q.empty()){auto tmp = q.top();q.pop();//插入返回的链表if (rethead == nullptr)rethead = rettail = tmp;else{rettail->next = tmp;rettail = rettail->next;}//放入队列if (tmp->next != nullptr){q.push(tmp->next);}}return rethead;}
};

思路3,归并,跟归并排序思路一致,每个链表单独都是一个有序的,每次合并就是把两个有序的链表合并。

每个链表要经历log k次的合并,而一共有k个链表,平均n个节点。复杂度就是n k log k

class Solution {
public:ListNode*merge(vector<ListNode*>&lists,int l,int r){if(l>r)return NULL;if(l==r)return lists[l];int mid=l+(r-l)/2;ListNode*head1=merge(lists,l,mid);ListNode*head2=merge(lists,mid+1,r);ListNode*ret=NULL,*retil=NULL;//合并两个有序链表while(head1&&head2){if(head1->val<head2->val){if(ret==NULL){ret=retil=head1;}else{retil->next=head1;retil=retil->next;}head1=head1->next;}else{if(ret==NULL){ret=retil=head2;}else{retil->next=head2;retil=retil->next;}head2=head2->next;}}while(head1){if(ret==NULL){ret=retil=head1;}else{retil->next=head1;retil=retil->next;}head1=head1->next;}while(head2){if(ret==NULL){ret=retil=head2;}else{retil->next=head2;retil=retil->next;}head2=head2->next;}return ret;}ListNode* mergeKLists(vector<ListNode*>& lists) {srand(time(NULL));return merge(lists,0,lists.size()-1);}
};

2.5K个一组翻转链表

25. K 个一组翻转链表 - 力扣(LeetCode)

本题思路模拟。先求出要逆序多少组。

然后依次逆序即可。

/*** 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* reverseKGroup(ListNode* head, int k) {ListNode*cur=head;int n=0;//先计算链表长度nwhile(cur){n++;cur=cur->next;}//然后计算需要多少组逆序n/=k;//依次开始逆序,利用头插方式cur=head;ListNode*rethead=new ListNode(0);ListNode*prev=rethead,*next=nullptr,*rettail=rethead;for(int i=0;i<n;i++){//每次都头插在prev后面。for(int j=0;j<k;j++){if(j==0)rettail=cur;//记得更新返回链表的末尾next=cur->next;cur->next=prev->next;prev->next=cur;cur=next;}prev=rettail;//prev每次都更新成返回链表的末尾即可}prev->next=cur;//把原链表剩下的内容链接上head=rethead->next;delete rethead;return head;}
};

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

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

相关文章

场景是人工智能第四要素,是垂直领域人工智能的第一要素。

"场景是人工智能的第四要素&#xff0c;与数据、算力、算法同等重要。"拿着技术找场景&#xff0c;还是拿着场景找技术&#xff1f;这个锤子和钉子的问题&#xff0c;一直困扰着各家AI大厂。从近5年的实践来看&#xff0c;拿着场景找技术是更为稳健的&#xff0c;否则…

哪款宠物空气净化器能更好的清理浮毛?希喂、352、IAM测评分享

家里这三只可爱的小猫咪&#xff0c;已然成为了我们生活中不可或缺的家庭成员&#xff0c;陪伴我们度过了说长不长说短不短的五年时光。时常庆幸自己当年选择养它们&#xff0c;在我失落的时候总能给我安慰&#xff0c;治愈我多时。 但这个温馨的背后也有一点小烦恼&#xff0…

ES6语法详解

以下是ES6常用的一些语法和特性&#xff1a; 声明变量的关键字变化&#xff1a;使用let和const、var来声明变量。 箭头函数&#xff1a;使用箭头&#xff08;>&#xff09;定义函数&#xff0c;简化函数的写法。 模板字符串&#xff1a;使用反引号&#xff08;&#xff0…

【java入门】关键字、标识符与变量初识

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…

Docker Elasticsearch安装ik分词插件教程

本章教程在通过Docker 安装Elasticsearch,并安装ik分词插件。本文的重点是安装ik分词插件。 一、安装Elasticsearch 安装教程以前写过,参考:https://blog.csdn.net/qq_19309473/article/details/140725121 安装之后,通过http://ip:9200,可以访问,就表示安装成功。 二、安装…

Linux终端简单配置(Vim、oh-my-zsh和Terminator)

文章目录 0. 概述1. 完整Vim配置2. Vim配置方案解释2.1 状态行与配色方案2.2 文件管理与缓存设置2.3 搜索与导航优化2.4 缩进与格式化设置2.5 粘贴模式快捷切换2.6 文件编码与格式2.7 性能优化 3. 安装 Oh My Zsh 及配置3.1 安装 Oh My Zsh3.2 Oh My Zsh 配置 3. Terminator终端…

vscode +STM32 VS CODE EXTENSION

stm32 vs code extersion 1.0.0版本可以直接导入cubeide的工程&#xff0c;之后版本不可以&#xff0c;所以为了省事&#xff0c;使用stm32 vs code extersion 1.0.0插件。 安装完stm32 vs code extersion插件&#xff0c;会默认把相关插件一起安装。但是需要手动安装Ninja&am…

交叉编译概念

交叉编译概念 目录 交叉编译概念1. 什么是交叉编译2. 交叉编译的作用3. 交叉编译器4. 交叉编译工具链5. 交叉编译的一般步骤6. 交叉编译实例 1. 什么是交叉编译 交叉编译是指在一个平台上编译代码&#xff0c;使其能够在另一个不同的平台上运行的过程。这种编译方式通常用于开…

Android12——Launcher3文件夹布局修改调整

文章声明&#xff1a;本文是笔者参考良心大佬作品后结合实际需求进行相应的定制&#xff0c;本篇主要是笔者记录一次解析bug笔记&#xff0c;文中可能会引用大佬文章中的部分图片在此声明&#xff0c;并非盈利目的&#xff0c;如涉嫌侵权请私信&#xff0c;谢谢&#xff01; 大…

什么是函数调用约定?

目录 前言 一、函数调用约定的主要内容 二、常见的函数调用约定 1. __cdecl&#xff08;C Declaration&#xff09; 2. __stdcall&#xff08;Standard Call&#xff09; 3. __fastcall&#xff08;Fast Call&#xff09; 4. __thiscall&#xff08;This Call&#xff0…

[数据集][目标检测]轮胎检测数据集VOC+YOLO格式4629张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4629 标注数量(xml文件个数)&#xff1a;4629 标注数量(txt文件个数)&#xff1a;4629 标注…

【SQL】删除表中重复数据的方法

很久之前我写入一张sql的数据表&#xff0c;它里面有很多重复的内容。然后我想只保留一条原始数据&#xff1a; 例如上面的时间&#xff0c;出现了很多重复值。 我最初用的是这种方法&#xff1a; SELECT * FROM table_name WHERE primary_key IN (SELECT max(primary_key)F…

仕考网:公务员笔试和面试哪个难?

公务员笔试和面试哪个难?二者之间考察的方向不同&#xff0c;难度也是不同的。 笔试部分因其广泛的知识点和有限的考试时间显得难度更高一些&#xff0c;在笔试环节中&#xff0c;考生需在有限的时间内应对各种问题&#xff0c;而且同时还要面对激烈的竞争&#xff0c;在众多…

栈栈栈专题

一、基础 Leetcode 3174. 清除数字 class Solution { public:string clearDigits(string s) {string st; // 用string模拟栈的行为for(auto& v: s){if(isdigit(v)) st.pop_back();else st v;}return st;} }; 二、进阶 三、邻项消除 四、合法括号字符串 五、…

50Kg大载重长航时油电混动多旋翼无人机技术详解

50Kg大载重长航时油电混动多旋翼无人机技术是一项高度复杂且前沿的研究领域&#xff0c;它结合了燃油发动机的高能量密度和电动机的高效性&#xff0c;旨在提高无人机的续航能力和载重能力。以下是对该技术的详细解析&#xff1a; 产品轴距&#xff1a;2320mm 产品尺寸&#x…

Django+Vue家居全屋定制系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 需要的环境3.2 Django接口层3.3 实体类3.4 config.ini3.5 启动类3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质创作者&…

今年读过最绝的大模型神书死磕这本大模型神书!看完直接脱胎换骨!!

书名&#x1f4d6;&#xff1a;《大语言模型&#xff1a;基础与前沿》 该书深入阐述了大语言模型&#xff08;Large Language Model, LLM&#xff09;的基本概念和算法、研究前沿以及应用&#xff0c;内容全面且系统性强&#xff0c;适合&#x1f468;&#x1f3fb;‍&#x1…

【Python系列】FastApi发送Post请求

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

安装 Let‘s Encrypt certbot 生成多个域名免费 https 证书实录(linux pip 方式)

本文记录了我在华为云 EulerOS linux 云主机使用 python pip 方式安装配置 Let’s Encrypt certbot, 并为我的网站的多个域名生成免费 https 证书的整个过程, 包括 python 环境配置, 下载 certbot 及 certbot-nginx, 一次性生成多个域名的证书及注意事项, 以及最后配置 certbot…

k8s配置

一、前期准备 1、修改主机的/etc/hosts文件挟持域名 [rootk8s-master ~]# vim /etc/hosts 192.168.8.199 k8s-master 192.168.8.200 k8s-node1 192.168.8.201 k8s-node2 2、配置yum源 [rootk8s-master ~]# cd /etc/yum.repos.d/ [rootk8s-master yum.repos.d]# vim kubernetes…