剑指offer面试题之求两个链表的第一个公共点
来源:互联网 发布:水岛宏 知乎 编辑:程序博客网 时间:2024/06/05 17:12
1,问题:
输入两个链表,找出它们的第一个公共结点。(现在只考虑都是无环的)
2,想法
(1),先求出两个链表的长度,用两个指针,长链表的指针先走长度之差那么多步,然后两个指针一起走,遇到指针相同的就返回。
(2),遍历两个链表,把指针入栈,然后再同时出栈,若遇到不相同的则返回上一个相同的栈元素。
3,编码为:
/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public: ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) { if (pHead1 == NULL || pHead2 == NULL) { return NULL; } /*int length1 = 0; int length2 = 0; ListNode* pNewHead1 = pHead1; ListNode* pNewHead2 = pHead2; bool flag = false; while (pNewHead1 != NULL) { length1++; pNewHead1 = pNewHead1->next; } while (pNewHead2 != NULL) { length2++; pNewHead2 = pNewHead2->next; } int count = 0; if (length1 >= length2) { count = length1 - length2; flag = true; } else count = length2 - length1; pNewHead1 = pHead1; pNewHead2 = pHead2; int i; for (i = 0; i < count; i++) { if (flag) { pNewHead1 = pNewHead1->next; } else pNewHead2 = pNewHead2->next; } while (pNewHead1 != NULL && pNewHead2 != NULL) { if (pNewHead1 == pNewHead2) { return pNewHead1; } else { pNewHead1 = pNewHead1->next; pNewHead2 = pNewHead2->next; } } return NULL; */ stack<ListNode*> temp1; stack<ListNode*> temp2; ListNode* pNewHead1 = pHead1; ListNode* pNewHead2 = pHead2; while (pNewHead1) { temp1.push(pNewHead1); pNewHead1 = pNewHead1->next; } while (pNewHead2) { temp2.push(pNewHead2); pNewHead2 = pNewHead2->next; } pNewHead1 = NULL; pNewHead2 = NULL; while (!temp1.empty() && !temp2.empty()) { if (temp1.top() == temp2.top()) { pNewHead1 = temp1.top(); pNewHead2 = temp2.top(); temp1.pop(); temp2.pop(); } else return pNewHead1; } return pNewHead1; }};4,若链表有环,怎么找到环的入口?
(1),设两个指针,初始都为头指针,一个slow指针,每次走一步,另一个fast指针,每次走两步,若有环,则必定相遇。找到相遇点后,slow指针重回头指针,而fast指针在相遇点,两个指针同时走,每次都走一步,下次必在入口点相遇。
5,若两个链表都可能有环,怎么计算出第一个公共点?
想法(1):
还是计算两个链表的长度,至于判断重复访问问题,用一个map<node*, int>来判断。若已经访问过了就break,不然就加入到map中。
具体代码:
<pre name="code" class="cpp">// 循环链表第一个公共节点.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <map>#include <iostream>using namespace std;class node{public:int data;node* next;node(){};node(int x):data(x),next(NULL){};};node* FindFirstCommonNode(node* p1, node* p2){if (p1 == NULL || p2 == NULL){return NULL;}map<node*, int> mp1;map<node*, int> mp2;node *p1new = p1;node *p2new = p2;int length1 = 0;int length2 = 0;bool flag = false;while (p1new != NULL){if (mp1.count(p1new))//表示已经访问过了{break;}else{mp1[p1new] = 1;length1++;p1new = p1new->next;}}while (p2new != NULL){if (mp2.count(p2new)){break;}else{mp2[p2new] = 1;length2++;p2new = p2new->next;}}p1new = p1;p2new = p2;int count = 0;if (length1 >= length2){count = length1 - length2;flag = true;}elsecount = length2 - length1;for (int i = 0; i < count; i++){if (flag){p1new = p1new->next;}elsep2new = p2new->next;}while (p1new != NULL && p2new != NULL){if (p1new == p2new){return p1new;}else{p1new = p1new->next;p2new = p2new->next;}}return NULL;}int _tmain(int argc, _TCHAR* argv[]){node* p1Head = NULL;node* p2Head = NULL;//以下代码是随便建立的两个链表,不必深究node* p1 = new node(1);p1Head = p1;int temp = -1;node* dd = NULL;int num;while (temp != 0){cin >> num;temp = num;if (temp != 0){p1->next = new node(temp);p1 = p1->next;if (temp == 4)//节点值为4的为第一个公共节点{dd = p1;}}}p1 = p1Head;while (p1){cout << p1->data << endl;p1 = p1->next;}temp = -1;node* p2 = new node(6);p2Head = p2;while (temp != 0){cin >> num;temp = num;if (temp != 0){p2->next = new node(temp);p2 = p2->next;}}p2->next = dd;//第二个链表从节点值为4的那里开始链接第一个链表的后续结点p2 = p2Head;while (p2){cout << p2->data << endl;p2 = p2->next;}node* c = FindFirstCommonNode(p1Head, p2Head); cout << c->data << endl;system("pause");return 0;}
1 0
- 剑指offer面试题之求两个链表的第一个公共点
- 剑指offer面试题 求两个链表的第一个公共结点
- 【面试题】剑指Offer-37-求两个链表的第一个公共节点
- 剑指offer之面试题37两个链表的第一个公共结点
- 剑指Offer之面试题37:两个链表的第一个公共结点
- 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
- 剑指offer面试题37 两个链表的第一个公共节点
- [剑指offer][面试题37]两个链表的第一个公共节点
- 【剑指offer】面试题37:两个链表的第一个公共结点
- [剑指offer]面试题37:两个链表的第一个公共结点
- 剑指Offer:面试题37 两个链表的第一个公共结点
- 剑指offer 面试题37 两个链表的第一个公共结点
- 剑指offer 面试题37—两个链表的第一个公共节点
- 《剑指Offer》学习笔记--面试题37:两个链表的第一个公共结点
- 【剑指Offer学习】【面试题37:两个链表的第一个公共结点】
- 剑指Offer面试题37(Java版):两个链表的第一个公共结点
- 《剑指Offer》面试题:寻找两个链表的第一个公共节点
- 剑指offer-面试题37.两个链表的第一个公共结点
- smarty模板引擎_9-Smarty模板的继承特性
- 水题 hdoj-2006奇数偶数判断小技巧 、 hdoj-2007
- Scalaz(36)- Free :实践-Free In Action - 实用体验
- 笔试题总结
- 1. Two Sum
- 剑指offer面试题之求两个链表的第一个公共点
- Android 工具类 Toast Log.d()
- 数据处理之文件读写
- IMF百日大喜超大活动
- Sublime text 2/3 中 Package Control 的安装与使用方法+激活汉化方法
- Bzoj2565:最长双回文串:回文自动机
- Linux内核分析实验五
- 如何写圆角布局(布局加圆角表框)
- 前端web开发的MVC模式-从一个简单的实例讲起