判断两个链表是否相交,若相交,求交点,考虑带环情况实现代码
来源:互联网 发布:bmp和jpg的区别 知乎 编辑:程序博客网 时间:2024/05/29 02:40
梳理一下思路
思路
相当于求俩个链表的第一个公共结点,要么找到,要么为空,那么考虑到有链表可能有带环的情况,情况共分为下面三种:
(1)、两个链表都带环
分别获取两个链表环的入口点
判断入口点是否相同
如果入口点相同,临时修改链表为 Y 形状,处理完毕后恢复
如果入口点不相同,将一个环遍历一周看是否能遇到另外一个环的入口点(防止单独成环)(2)、两个链表都不带环
都无环,当做 Y 形状处理
(3)、一个带环一个不带环
这种情况肯定不相交,画几个图就想明白了。
关于(1),可以看下面这个图:
/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/
class Solution {public: // 找出链表的第一个公共结点 ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { // 第一个公共结点 ListNode* commonNode = NULL; if(pHead1 == NULL || pHead2 == NULL ) return NULL; // (1) 判断是否都有环 ListNode* circleNode1; // 链表1 环上的结点(快慢指针相遇点),如果无环则为空 ListNode* circleNode2; // 链表2 环上的结点(快慢指针相遇点),如果无环则为空 circleNode1 = GetMeetNode(pHead1); circleNode2 = GetMeetNode(pHead2); // (2) 如果都有环 or 如果都无环 or 只有一个有环 // 1. 都有环 if (circleNode1 && circleNode2){ // 链表1 环的入口点 ListNode* circleEnterNode1 = GetCircleEnterNode(pHead1, circleNode1); // 链表2 环的入口点 ListNode* circleEnterNode2 = GetCircleEnterNode(pHead2, circleNode2); // 如果入口点相同,临时修改链表为 Y 形状,处理完毕后恢复 if(circleEnterNode1 == circleEnterNode2){ // 保存 ListNode* enterNodeNext = circleEnterNode1->next; // 设置为 Y 形,即无环 circleEnterNode1->next = NULL; // 调用处理无环情况的函数 commonNode = GetFirstCommonNodeNoCircle(pHead1, pHead2); // 恢复 circleEnterNode1->next = enterNodeNext; }// 如果入口点不同,将一个环遍历一周看是否能遇到另外一个环的入口点 else{ // 获取其中一个环的长度 int circleLength = GetCircleLength(circleNode2); // 遍历一周看是否能遇到另外一个环的入口点,如果遇到则找到,否则未找到返回环 ListNode* next = circleEnterNode2->next; // 遍历一圈 while(circleLength--){ // 找到公共结点 if(next == circleEnterNode1){ commonNode = circleEnterNode1; break; } next = next->next; } // 未找到公共结点 if(circleLength <= 0) return NULL; } } // 2. 都无环 else if (circleNode1 == NULL && circleNode2 == NULL){ commonNode = GetFirstCommonNodeNoCircle(pHead1, pHead2); } // (3).其中一个无环, 肯定无公共结点 return commonNode; }private: // 获取带环链表环上的一个结点(快慢指针相遇点),如果不带环则返回空 ListNode* GetMeetNode(ListNode* pHead){ if(pHead == NULL) return NULL; ListNode* pFast = pHead; ListNode* pSlow = pHead; // 快慢指针法 while(pFast && pFast->next){ pFast = pFast->next->next; pSlow = pSlow->next; if(pFast == pSlow){ return pFast; } } return NULL; } // 根据快慢指针相遇点,过去环的入口点 ListNode* GetCircleEnterNode(ListNode* pHead, ListNode* meetNode){ if(pHead == NULL || meetNode == NULL) return NULL; while(pHead != meetNode){ pHead = pHead->next; meetNode = meetNode->next; } return pHead; } // 判断两个链表是否相交 bool isCross(ListNode* pHead1, ListNode* pHead2){ if(pHead1 == NULL || pHead2 == NULL){ return false; } while(pHead1->next) pHead1 = pHead1->next; while(pHead2->next) pHead2 = pHead2->next; if(pHead1 == pHead2) return true; return false; } // 获取链表长度 int getListLength(ListNode* pHead){ int length = 0; while(pHead){ length++; pHead = pHead->next; } return length; } // 处理 Y 形状 ListNode* GetFirstCommonNodeNoCircle(ListNode* pHead1, ListNode* pHead2){ if(pHead1 == NULL || pHead2 == NULL) return NULL; // 如果不相交,直接返回NULL if (!isCross(pHead1, pHead2)) return NULL; int step = 0; int lengthList1 = getListLength(pHead1); int lengthList2 = getListLength(pHead2); step = lengthList1 - lengthList2; if(step > 0){ while(step--) pHead1 = pHead1->next; } else if(step<0){ while(step++) pHead2 = pHead2->next; } while(pHead1 != pHead2){ pHead1 = pHead1->next; pHead2 = pHead2->next; } return pHead1; } // 获取带环链表环的长度 int GetCircleLength(ListNode* meetNode){ int length = 0; if(meetNode == NULL) return length; ListNode* next = meetNode->next; while(next != meetNode){ length++; next = next->next; } return length; }};
阅读全文
0 0
- 判断两个链表是否相交,若相交,求交点,考虑带环情况实现代码
- 判断两个链表是否相交,若相交,求交点:1.不带环。2.有可能带环
- 判断两个链表是否相交,若相交,求交点,若带环呢/fork继承问题
- 判断俩个链表是否相交,若相交求交点(考虑带环和不带环)
- 判断两个链表是否相交,若相交,求交点。
- 判断两个链表是否相交,若相交,求交点
- 判断两个链表是否相交,若相交,求交点
- ]数据结构:单链表之判断两个链表是否相交及求交点(带环、不带环)
- 1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
- 链表--1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
- 1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
- 求两个链表是否相交,若相交,求交点(链表可能带环)
- 判断两个链表是否相交,若相交,求交点。(假设链表带环、不带环)
- 判断两个链表是否相交,若相交,求交点。(假设链表不带环)(C语言)
- 判断两链表是否相交,若相交求交点(链表可能带环)
- 每日一刷——1.判断两个链表是否相交,若相交求交点(链表不带环&带环)2.fork()问题
- 判断两个不带环链表是否相交?若相交,求入口点。
- 判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】(C语言)
- OCP 关于enum的坑
- struts2
- 多泳道(队列)问题 标准输出问题
- NG之Route模块路由配置
- 1029 Ignatius and the Princess IV
- 判断两个链表是否相交,若相交,求交点,考虑带环情况实现代码
- 1241 Oil Deposits
- Leetcode 159. Longest Substring with At Most Two Distinct Characters
- U盘启动无法使用键盘与鼠标
- linux下保护视力、定时强制锁定软件: Workrave
- php5.5新特性之yield理解
- 拆机(装机)后开机黑屏并且一直发出滴滴滴的声音
- phoenix for cloudera
- 重装系统后卡在 Verifying DMI Pool Data