链表带环问题1
来源:互联网 发布:js获取tr的第一个td 编辑:程序博客网 时间:2024/04/27 21:38
给出一个链表;
1.判断其是否带环?
2.如果带环求环的长度?
3.求环的入口节点?
解题思路:
用两个指针,快指针一次走两步,慢指针一次走一步,如果两指针相遇,那么链表带环,若两指针不相遇,则链表不带环。
带环的几种情况:Node* List::find_meet_node(Node* Head){if(Head==NULL)return NULL;if(Head->_next ==Head)return Head;Node* entry=NULL;Node* fast=Head;Node* slow=Head;while(fast){fast=fast->_next ->_next ;slow=slow->_next ;if(fast==slow)return fast;}return NULL;}void List::IsHasRing(Node* Head){Node* ret=find_meet_node(Head);if(ret==NULL)cout<<"no ring"<<endl;elsecout<<"have a ring"<<endl;}
2.求环的长度:
解题思路:
面试题1已经判断过链表带环,且返回两指针相遇节点,求环长度时我们可以让一个指针从相遇节点处开始遍历,当再次回到相遇节点时,它走过的步数就是环的长度。
int List::ring_len(Node* meet){if(meet==NULL)return 0;Node* cur=meet->_next ;int len=1;while(cur!=meet){cur=cur->_next; len++;}return len;}
3.求环的入口节点:
方法一:假设上图是一个单链表,两指针走到相遇节点时,慢指针走了L+X步,快指针走了L+X+nC步,(l为环的长度),由于快指针速度是慢指针速度的一倍,那么就有以下的等式:
(L+X)*2=L+X+nC;化解可得:L=nC-X;
那解题时我们可以用两个指针,一个指针从链表的开始位置走,另一个指针从相遇的节点处开始走,也就是y,两个指针相遇的节点就是入口点。
Node* List::find_entry(Node* Head,Node* meet){if(meet==NULL)return NULL;Node* prev=Head;Node* post=meet;while(prev!=post){prev=prev->_next ;post=post->_next ;}return prev;}
方法二:将相遇的节点处断开,转化为两条链表相交求交点问题,两个指针meet和Entry分别遍历到链表尾,记录两链表的长度len_l1和len_l2,然后让较长的链表先走len=|len_l1 - len_l2|步,然后两指针一起走,直到两指针相遇,相遇的节点就是链表的交点,即环的入口点。
Node* List::find_entry(Node* Head,Node* meet){ pLinkNode Entry = head; pLinkNode meet = MeetNode->next; int len_head = 0; int len_meet = 0; int len = 0; while (Entry != MeetNode) //求链表长度 { len_head++; Entry = Entry->next; } while (meet != MeetNode)//求链表长度 { len_meet++; meet = meet->next; } Entry = head; meet = MeetNode->next; if (len_head > len_meet) { len = len_head - len_meet; while (len--) { Entry = Entry->next; }//较长链表先走len=|len_l1 - len_l2|步 } else { len = len_meet - len_head; while (len--) { meet = meet->next; }//较长链表先走len=|len_l1 - len_l2|步 } while (meet != Entry) { Entry = Entry->next; meet = meet->next; } //两指针同时走,相遇节点就是环入口点 return Entry;}
测试用例:
void test3()//测试是否带环{List l;Node* node1=new Node(0);Node* node2=new Node(1);Node* node3=new Node(2);Node* node4=new Node(3);Node* node5=new Node(4);Node* node6=new Node(5);Node* node7=new Node(6);node1->_next =node2;node2->_next =node3;node3->_next =node4; node4->_next =node5;node5->_next =node6;node6->_next =node5; l.IsHasRing(node1);Node* meet=l.find_meet_node(node1);cout<<"meet:"<<meet->_data <<endl;int len=l.ring_len(meet);cout<<"length:"<<len<<endl;Node* entry=l.find_entry(node1,meet);cout<<"entry:"<<entry->_data <<endl;}
运行结果:
到此结束!
阅读全文
0 1
- 链表带环问题1
- 链表带环问题
- 单链表带环问题
- 单链表带环问题
- 单链表带环问题
- 有关单链表带环的问题
- 链表带环问题【每日一题】
- 面试题----单链表带环问题
- 链表带环和相交的问题
- 【每日一题-3】链表带环问题
- 链表带环的问题研究及代码实现
- 关于单链表带环的一系列问题
- 单链表带环的一系列问题
- 链表面试题3/链表带环问题--判断链表是否带环?
- 链表常见面试题三:解决链表带环问题
- c/c++单链表面试题—链表带环问题
- 链表面试题(三):链表相交,链表带环,链表带环相交
- 链表带不带头结点
- 截取字符串中的数字转为int
- 红黑树详细介绍
- 05.12 架构之ssh-key章节
- 简单的bat批处理脚本辅助卸载更新android app
- shell脚本截取字符串
- 链表带环问题1
- Python基础(二、代码调试方式dir,help,print函数,pycharm破解教程)
- 设计一个类不能被继承;只能在堆上创建对象;只能在栈上创建对象
- BZOJ3329 Xorequ
- linux服务篇-sshd服务管理与防止暴力破解
- 点击其他区域,input输入框不失去焦点
- Redis数据结构详解
- java实现筛选数三个double类型的数中的最大值
- mysql修改root密码