两个链表的公共链表

题目:有两个较长的单向链表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;
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值