两个链表的公共链表

来源:互联网 发布:淘宝店运费怎么设置 编辑:程序博客网 时间:2024/06/10 15:00

题目:有两个较长的单向链表a和b,为了找出节点node满足node in a并且node in b,请设计空间使用尽量小的算法。

来源:阿里巴巴 2014秋校园招聘 软件研发 笔试卷 27题

思路:若两个链表有公共部分,则这两个链表的结构类似于Y型。首先遍历两个链表到尾指针同时记下两个链表的长度m, n,若尾指针不同,则没有公共链表。然后使用两个指针重头遍历,让长链表的指针先走|m-n|步,使得当遇到公共节点的时候,快慢指针能同时到达。整体复杂度为O(m+n)。

代码如下:

#include <iostream>using namespace std;struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {} };class Solution {public:ListNode *commonList(ListNode *h1, ListNode *h2) {int m = 0, n = 0;ListNode *cur1 = h1, *cur2 = h2;while(cur1->next != NULL) {m++;cur1 = cur1->next;}while(cur2->next != NULL) {n++;cur2 = cur2->next;}//若链表的尾节点不同,则没有公共链表 if(cur1 != cur2)return NULL;cur1 = h1, cur2 = h2;int dis = m > n ? m-n : n-m;//较长的链表先走dis步 if(m >= n) {while(dis--)cur1 = cur1->next;}else {while(dis--)cur2 = cur2->next;}while(cur1 != NULL && cur2 != NULL) {if(cur1 == cur2)return cur1;cur1 = cur1->next;cur2 = cur2->next; }}};int main() {//测试 ListNode *head1 = new ListNode(1);head1->next = new ListNode(4);head1->next->next = new ListNode(3);ListNode *head2 = new ListNode(2);head2->next = new ListNode(5);head2->next->next = head1->next;head2->next->next->next = head1->next->next;Solution s;ListNode *res = s.commonList(head1, head2);while(res != NULL) {cout << res->val << " ";res = res->next;}while(head1 != NULL) {ListNode *tmp = head1;head1 = head1->next;delete tmp;}while(head2 != NULL) {ListNode *tmp = head2;head2 = head2->next;delete tmp;}return 0;} 



0 0