链表 oj2 (7.31)

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

我们通过头插来实现

将链表上的节点取下来(取的时候需要记录下一个节点),形成新的链表,对新的链表进行头插。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/struct ListNode* reverseList(struct ListNode* head)
{//用cur对原链表进行遍历struct ListNode* cur=head,*newhead=NULL;//原链表为空,遍历结束while(cur){//记录cur的下一个节点struct ListNode* next=cur->next;//cur链接到新链表cur->next=newhead;//cur成为新链表的头指针newhead=cur;//cur通过next在原链表中向后移cur=next;}return newhead;
}

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

这里需要引用哨兵位,先介绍一下

    

哨兵位就是不带数据的头节点,且为固定的节点,当链表为空时,带哨兵位的链表(右)存在一个头节点(空间),而不带哨兵位的链表(左)则没有节点。

更改带哨兵位的链表(增删查改)就不需要判断,通过二重指针改变头指针,通过 next 就能直接实现。

使用的时候为哨兵位申请一块动态内存,作为头节点,结束的时候可以根据题目要求将其释放。

实现:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){if(list1==NULL){return list2;}if(list2==NULL){return list1;}struct ListNode* head=NULL,*tail=NULL;//带一个哨兵位,方便尾插head=tail=(struct ListNode*)malloc(sizeof(struct ListNode));while(list1&&list2){if(list1->val<list2->val){tail->next=list1;tail=tail->next;list1=list1->next;}else{tail->next=list2;tail=tail->next;list2=list2->next;}}//if(list2){tail->next=list2;}if(list1){tail->next=list1;}//哨兵位的头使用完需要释放掉struct ListNode* del=head;head=head->next;free(del);return head;
}

链表分割_牛客题霸_牛客网 (nowcoder.com)

思路是创建两个链表,将小于 x 的尾插到第一个链表,大于 x 尾插到第二个链表。

此题目用带哨兵位的链表做更加简单,因为尾插时不用考虑链表是否为空的情况,将两个链表链接的时候也不需要考虑其中一个链表为空的情况了(即不用担心链表为空的情况)。

/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
#include <cstddef>
class Partition {public:ListNode* partition(ListNode* pHead, int x) {struct ListNode* ghead, *gtail, *lhead, *ltail;ghead = gtail = (struct ListNode*)malloc(sizeof(struct ListNode));lhead = ltail = (struct ListNode*)malloc(sizeof(struct ListNode));//用cur遍历struct ListNode* cur = pHead;while (cur){if(cur->val < x){ltail->next = cur;ltail = ltail->next;}else{gtail->next = cur;gtail = gtail->next;}cur = cur->next;}//将低链表的尾链接到高链表的哨兵位之后的节点ltail->next = ghead->next;//将目标链表的尾置空,否则产生环gtail->next = nullptr;//拷贝目标链表的头节点struct ListNode* head = lhead->next;//释放哨兵位free(lhead);free(ghead);return head;}
};

链表的回文结构_牛客题霸_牛客网 (nowcoder.com)

回文结构就是对称的意思,例如 1 2 2 1,1 2 3 2 1。

结合前面的 oj 题目,我们容易想到一个方法,先找出链表的后半段,然后将其逆置,再将其与前半段比较,如果都相同,则为回文结构。

/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public://反转链表struct ListNode* reverseList(struct ListNode* head)
{//用cur对原链表进行遍历struct ListNode* cur=head,*newhead=nullptr;//原链表为空,遍历结束while(cur){//记录cur的下一个节点struct ListNode* next=cur->next;//cur链接到新链表cur->next=newhead;//cur成为新链表的头指针newhead=cur;//cur通过next在原链表中向后移cur=next;}return newhead;
}//找出中间节点struct ListNode* middleNode(struct ListNode* head){struct ListNode* slow=head,*fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;}return slow;
}bool chkPalindrome(ListNode* head) {//找出后半段struct ListNode* mid=middleNode(head);//将后半段逆置struct ListNode* rmid=reverseList(mid);while(rmid&&head){if(rmid->val!=head->val){return false;}rmid=rmid->next;head=head->next;}return true;}
};

160. 相交链表 - 力扣(LeetCode)

思路:

1.遍历计算出A,B链表各自的长度 lenA,lenB

2.长的链表走差距步 lenA-lenB,此时两条链表的长度相同

3.同时移动找交点(指针相同),最后返回这个交点。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* curA=headA,*curB=headB;int lenA=1,lenB=1;//提示了链表不为空,因此结尾用下一个节点判断,同时初始长度为1while(curA->next){curA=curA->next;lenA++;}while(curB->next){curB=curB->next;lenB++;}//尾节点不同,一定没有交点if(curA !=curB){return NULL;}struct ListNode* longList=headA,*shortList=headB;if(lenA<lenB){longList=headB;shortList=headA;}//算出差距步(绝对值)int gap=abs(lenA-lenB);//长的先走差距步while(gap--){longList=longList->next;}//同时走找交点,相等就找到了while(longList !=shortList){longList=longList->next;shortList=shortList->next;}return longList;
}

141. 环形链表 - 力扣(LeetCode)

链表有循环或者非循环

循环链表的尾节点指向头节点。

还有一种带环链表,它的尾节点可以指向链表的任意一个节点(包括自己)。

带环链表中的节点会重复出现,我们依然定义一快一慢指针,如果是带环链表,那么快指针一定能追上慢指针,两个指针一定有相等的时候(追及问题);如果不带环,直接就遍历到空了。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
bool hasCycle(struct ListNode *head) {struct ListNode* fast=head,*slow=head;//链表可能不为环形while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(slow==fast){return true;}}return false;
}

由带环追及问题引发的思考:

1.slow走一步,fast走两步,一定能追上吗,会不会错过?

2.slow走一步,fast走n步(n>=3),一定能追上吗,会不会错过?

如果 slow 走一步,fast 走三步,假设 slow 入环时,slow 和 fast 的距离为 M,每移动(追击)一次,距离缩小2,若 M 为偶数,则当距离减为0时,刚好追上;若 M 为奇数,距离最小时为 -1,即fast 超过了 slow 一步,此时又要观察环的长度C,此时 slow 和 fast 的距离为 C-1,若 C 为奇数,C-1为偶数,那么再经过一轮追击之后就能刚好追上。如果 C 为偶数,那么 C-1 为奇数,奇数-2 永远为奇数,就永远追不上了。 

142. 环形链表 II - 力扣(LeetCode)

分析:

设七点到入口长度:L

环的周长:C

入口点到相遇点的距离:X

fast 走的距离(速度)为 slow 的二倍

slow 进环后的一圈内,fast 一定追上 slow,slow 走的距离为 L+X

slow 进环时,fast 已经走了 n(n>=1) 圈了,fast 走的距离为 L+n*C+X

fast 追赶 slow 之前会先补足 n 圈,

fast 走的距离(速度)为 slow 的二倍可知

2(L+X)=L+n*C+X

同减去L+X

L+X=n*C

L=n*C-X

计算的时候我们默认为 fast 已经跑到 n-1 圈,因此不需要关注 n .

从这个结论我们可以得到从相遇点到环入口点的距离从起点到入口点的距离相同,要想找到入口点,就需要两个指针分别从这两个点开始跑,它们相遇的位置就是入口点。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode* fast,*slow;fast=slow=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;//相遇if(slow==fast){//记录相遇点struct ListNode* meet=slow;//各自从相遇点和头节点开始跑,相遇则为入口点while(head!=meet){head=head->next;meet=meet->next;}return meet;}}//fast或fast的下一个节点为空,说明无环return NULL;
}

法2:

将环从相遇点断开,相遇点之后作为一条新的链表,和旧链表一起找相交点,相交点就是入口点。

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

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

相关文章

STL库——Vector常见使用接口

一、介绍 1. vector是表示可变大小数组的序列容器&#xff0c;就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的&#xff0…

基于 Triple 实现 Web 移动端后端全面打通

*作者&#xff1a;陈有为&#xff0c;陌陌研发工程师、Apache Dubbo PMC RPC 协议开发微服务 在我们正常开发微服务的时候&#xff0c;传统 RPC 服务可能在最底层。上层可能是浏览器、移动端、外界的服务器、自己的测试、curl 等等。我们可能会通过 Tomcat 这种外部服务器去组…

​蔚来 V2G:带你重新了解如何参与构建新型电力系统

8 月 23 号&#xff0c;蔚来低调的在官方社区社区内发布了一条推文&#xff0c;推文为 「蔚来参与全国最大规模 V2G 需求响应」。 而车网互动验证中心(简称 e-Park)的 V2G 试验&#xff0c;在江苏无锡正式启动。 本次响应时间为 30 分钟&#xff0c;50 台电动车送电近 2000kW…

手术麻醉临床信息管理系统源码,客户端可以接入监护仪、麻醉机、呼吸机

一、手术麻醉临床信息管理系统介绍 1、手术麻醉临床信息管理系统是数字化手段应用于手术过程中的重要组成部分&#xff0c;用数字形式获取并存储手术相关信息&#xff0c;既便捷又高效。既然是管理系统&#xff0c;那就是一整套流程&#xff0c;管理患者手术、麻醉的申请、审批…

传输层协议(TCP/UDP协议)

全文目录 端口号端口号范围划分 传输层UDP协议特点基于UDP的应用层协议 TCP协议确认应答机制&#xff08;可靠性&#xff09;延迟应答机制超时重传机制流量控制连接管理机制TIME_WAIT 状态CLOSE_WAIT 状态拥塞控制滑动窗口 TCP、UDP对比TCP的listen第二个参数 端口号 在套接字…

【ELK 使用指南 1】ELK + Filebeat 分布式日志管理平台部署

ELK和EFLK 一、前言1.1 日志分析的作用1.2 需要收集的日志1.3 完整日志系统的基本特征 二、ELK概述2.1 ELK简介2.2 为什么要用ELK?2.3 ELK的组件 三、ELK组件详解3.1 Logstash3.1.1 简介3.1.2 Logstash命令常用选项3.1.3 Logstash 的输入和输出流3.1.4 Logstash配置文件 3.2 E…

用JavaScript输出0-9的两种方法、以及setTimeout的三个参数的意义

方法一&#xff1a; for (let i 0; i < 10; i) {setTimeout(() > {console.log(i);}, 1000) } 方法二&#xff1a;利用 setTimeout 函数的第三个参数&#xff0c;会作为回调函数的第一个参数传入 for (var i 0; i < 10; i) {setTimeout(i > {console.log(i);…

java springboot 实现 对象或对象数组 转为 前端可解析的JSON字符串格式

这是我的接口代码 逻辑就是 通过 IBookService对象中的 list 函数获取数据列表 然后定义 state(响应状态) message(提示信息) 最后将这三个信息 做成对象返回给前端 接口访问结果 但是这种对象数组对存储空间消耗肯定是比字符串大很多的 所以 我们来尝试 将json数组转成字符…

Arduino Nano 引脚复用分析

近期开发的项目为气体传感器采集仪&#xff0c;综合需求&#xff0c;选取NANO作为主控&#xff0c;附属设备有 oled、旋转编码器、H桥板、蠕动泵、开关、航插等&#xff0c;主要是用现有接口怎么合理配置实现功能。 不管stm32 还是 Arduino 都要看清引脚图 D2 D3 引脚是两个外…

vector+算法sort与list+sort的效率比较,容易写错的地方原因探析

我写的代码&#xff1a; #include <iostream> using namespace std; #include <vector> #include <list> #include <algorithm> int main() {const int N 10000000;vector<int> v;list<int> l;for (int i 0; i < N; i){v.push_back(…

计算机网络 | 应用层

计算机网络 | 应用层 计算机网络 | 应用层应用层概述网络应用模型客户/服务器模型&#xff08;Client/Server&#xff0c;C/S&#xff09;P2P模型&#xff08;Peer-to-Peer&#xff09; 域名系统&#xff08;DNS&#xff09;层次域名空间域名服务器域名解析过程 文件传输协议&a…

Ubuntu的Python从2.x升级到3.x

我的Ubuntu系统默认是2.7,我想升级为3.5 升级python3.5 下载python sudo apt-get install python3查看 刚才下载的Python程序被安装在usr/local/lib/python3.5 中 cd usr/local/lib备份一下 sudo cp /usr/bin/python /usr/bin/python_bak删除python的旧关联 sudo rm -rf py…