您的位置:首页 > 文旅 > 美景 > 郑州中心城区_合肥网站seo技术_seo推广和百度推广的区别_网络营销计划书怎么写

郑州中心城区_合肥网站seo技术_seo推广和百度推广的区别_网络营销计划书怎么写

2024/12/27 20:42:53 来源:https://blog.csdn.net/huayimenghan/article/details/143840092  浏览:    关键词:郑州中心城区_合肥网站seo技术_seo推广和百度推广的区别_网络营销计划书怎么写
郑州中心城区_合肥网站seo技术_seo推广和百度推广的区别_网络营销计划书怎么写

LeetCode 热题 100_环形链表 II(26_142)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
        • 代码实现(思路一(哈希表)):
        • 代码实现(思路二(快慢指针)):

题目描述:

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置**(索引从 0 开始)**。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

输入输出样例:

示例 1:
请添加图片描述

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:
请添加图片描述

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:
请添加图片描述

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

提示:
链表中节点的数目范围在范围 [0, 104] 内
-105 <= Node.val <= 105
pos 的值为 -1 或者链表中的一个有效索引

题解:

解题思路:

思路一(哈希表)
1、创建一个哈希集合用于存储遍历过的链表结点,如果当前遍历的结点不在哈希集合中则存入集合,如果当前遍历的结点存在哈希集合中则为链表开始入环的第一个节点,返回该结点程序结束。

2、复杂度分析:
① 时间复杂度:O(N),其中 N 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。
② 空间复杂度:O(N),其中 N 为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。

思路二(快慢指针):
1、通过题目分析,我们需要找到链表开始入环的第一个节点,通过分析我们可以得出下图(a代表环状链表之前的节点数,b代表环装链表的节点数):
请添加图片描述
fast=2slow(每次fast走两步,slow走一步)
fast=slow+n
b (b代表环中结点的个数,nb代表slow==fast时,fast比slow多在环中转了多少圈)
两式联立可得fast=2n
b,slow=n*b。

如果我们从头开始遍历结点到环的入口结点需要走:a+mb步。m取值为(0,1,2,…)
我们发现 slow=n
b 再走 a 步,也就是 a+n*b正好满足到达入口结点的条件。
我们这里的a的大小不知道怎么办,我们发现从首结点开始到入口正好为a步,所以我们从head和slow(fast==slow时)同时移动则会在环形入口处相遇。

2、具体思路如下:
① 定义两个指针,fast和slow,fast每次走两步,slow每次走一步。
② 通过遍历找到找到环中slow==fast的点(如果fast遍历到nullptr则不存在环,也就不存在环的入口结点)
③ 然后再令fast指向首结点,将fast和slow同时进行移动,这时fast每次移动一步,直到slow ==fast此时指向的结点为环的入口结点。

3、复杂度分析
① 时间复杂度:O(N),第二次相遇中,慢指针须走步数 a<a+b;第一次相遇中,慢指针须走步数 a+b−x<a+b,其中 x 为双指针重合点与环入口距离;因此总体为线性复杂度;
② 空间复杂度:O(1),双指针使用常数大小的额外空间。

代码实现(思路一(哈希表)):
ListNode *detectCycle1(ListNode *head) {unordered_set<ListNode*> mp_set;//创建一个哈希集合用于存储遍历过的链表结点,如果当前遍历的结点不在哈希集合中则存入集合,如果前遍历的结点存在哈希集合中(第一个)则为链表开始入环的第一个节点,返回该结点程序结束。while(head!=nullptr){if(mp_set.count(head)){return head;}else{mp_set.insert(head);head=head->next;}}return nullptr;
}
代码实现(思路二(快慢指针)):
ListNode *detectCycle2(ListNode *head) {ListNode *slow=head,*fast=head;//如果是无环的情况便返回,存在环则slow=fast结束循环 while(true){ if(fast==nullptr||fast->next==nullptr){return nullptr;}fast=fast->next->next;slow=slow->next;if(fast==slow){break;}}//将fast更改为首节点位置,这里fast和slow移动一步,相遇节点为开始入环的第一个节点 fast=head;while(fast!=slow){fast=fast->next;slow=slow->next;}return fast;}

以思路二为例完成代码调试

#include<iostream>
#include<vector>
#include<unordered_set>
using namespace std;struct ListNode{int val;ListNode *next;ListNode(int x):val(x),next(nullptr){}
};//尾插法创建单链表 
ListNode* createList(const vector<int> &a){ListNode *head=nullptr,*tail=nullptr;for(const auto &val:a){ListNode *newNode=new ListNode(val);if(head==nullptr){head=newNode;tail=newNode;}else{tail->next=newNode;tail=newNode;}}return head;
}//将单链表变成环形单链表(这里只是末尾存在环的情况) 
ListNode* createCircularList(ListNode *head,int pos){//无环则返回if(pos==-1){return head;} ListNode *posNode=head;//找到环的入口while(pos){posNode=posNode->next;--pos;}//找到链表的末尾ListNode *tail=posNode;while(tail->next!=nullptr){tail=tail->next;}//想成环tail->next=posNode;return head;
} //方法二(快慢指针)
ListNode *detectCycle2(ListNode *head) {ListNode *slow=head,*fast=head;//如果是无环的情况便返回,存在环则slow=fast结束循环 while(true){ if(fast==nullptr||fast->next==nullptr){return nullptr;}fast=fast->next->next;slow=slow->next;if(fast==slow){break;}}//将fast更改为首节点位置,这里fast和slow移动一步,相遇节点为开始入环的第一个节点 fast=head;while(fast!=slow){fast=fast->next;slow=slow->next;}return fast;
}
//主函数
int main(){vector<int> a={3,2,0,-4};int pos=1;ListNode *head=createList(a);ListNode *cir_head=createCircularList(head,pos);ListNode *ans=detectCycle2(cir_head);if(ans!=nullptr){cout<<"链表开始入环的第一个结点值为:"<<ans->val; }else{cout<<"链表没有开始入环的第一个结点";}return 0;
}

unordered_map和unordered_set对比及用法请点击此链接
ListNode(int x):val(x),next(nullptr){}解读请点击此链接
LeetCode 热题 100_环形链表 II(26_142)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com