leetcode每日一题链表有环无环链表长度求解

2023-11-10 10:10

本文主要是介绍leetcode每日一题链表有环无环链表长度求解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.链表有无环

采用快慢指针求解,指针slow和fast从链表头开始走,slow每次往后走一步,fast每次往后走两步,若链表有环则俩指针必定在环内相遇 

2.有环链表长度

如图所示,假设slow和fast在Pos处第一次相遇,join为环的入口,假设从表头Head到Join有l个节点,join沿逆时针到Pos有x个节点,环中有R个节点,显然fast走过的节点数是slow的两倍,那么有

                                                                             $$2(l + x) = l+nR+x$$                  (1)

其中$$n$$为一任意正整数,可以推出 

                                                                                      $$l=nR-x$$                           (2)

让fast和slow从Pos开始继续沿着逆时针走,同时用另外个指针p沿着Head一次走一步,到第二次相遇时fast比slow多走了一圈,而fast的速度刚好是slow的两倍,则slow刚好走了一圈,记下此时slow走过的节点数可以得到环内包含的节点数$$R$$,根据(2)可以得到,若slow从Pos走过$$l$$ 时刚好到达Join而此时p也刚好到达Join,记录下此时head走过的节点数$$l$$,则链表的长度为$$l+R$$

代码

struct Node {int data;Node* next;
};Node* IsCycle(Node *head)
{Node* slow = head;Node* fast = head;while (true) {if (fast == nullptr || slow == nullptr) {return nullptr;}slow = slow->next;fast = fast->next;if (fast == nullptr) {return nullptr;}fast = fast->next;if (fast == slow) {return fast;}}
}int LenList(Node* head)
{Node* Pos = IsCycle(head);if (Pos == nullptr) {return LenNonCycle(head);}int l = 0;int r = 0;bool rget = false;bool lget = false;Node* slow = Pos;Node* fast = Pos;Node* p = head;while(true) {slow = slow->next;if (!rget) {++r;}if (!lget) {++l;}fast = fast->next->next;if (fast == slow) {rget = true;}if (slow == p) {lget == true;}if (rget && lget) {return r + l;}}
}

 

这篇关于leetcode每日一题链表有环无环链表长度求解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/381999

相关文章

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

深入手撕链表

链表 分类概念单链表增尾插头插插入 删尾删头删删除 查完整实现带头不带头 双向链表初始化增尾插头插插入 删查完整代码 数组 分类 #mermaid-svg-qKD178fTiiaYeKjl {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

建立升序链表

题目1181:遍历链表 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2744 解决:1186 题目描述: 建立一个升序链表并遍历输出。 输入: 输入的每个案例中第一行包括1个整数:n(1<=n<=1000),接下来的一行包括n个整数。 输出: 可能有多组测试数据,对于每组数据, 将n个整数建立升序链表,之后遍历链表并输出。 样例输

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return