Intersection of Two Linked Lists

16 篇文章 0 订阅

Write a program to find the node at which the intersection of two singly linked lists begins.

For example, the following two linked lists:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

begin to intersect at node c1.

Notes:

  • If the two linked lists have no intersection at all, return null.
  • The linked lists must retain their original structure after the function returns.
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.
解题思路:1.首先想到的是哈希,先将一个链表中结点都插入字典中,然后遍历另一个链表中的结点看是否有结点在字典中;但这种方法需要开辟较大的内存空间来存储字典;

               2.双指针法.首先对其中一个链表头尾连接.那么问题就变成了看另一个链表是否存在环的问题了.但这种方法改变了原本链表的结构,需要在最后对其还原;

               3.先计算两个链表的长度差,然后对长链表头结点开始移动长度差长的结点,找到位置对应的结点.然后逐个比较是否相等;

#include<iostream>
#include<vector>
#include<set>
using namespace std;

//Definition for singly - linked list.
struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
//解法一: 哈希 Submission Result: Memory Limit Exceeded
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
	set<ListNode*>NodeSet;
	for (; headA != NULL;headA = headA->next)
		NodeSet.insert(headA);
	while (headB!=NULL)
	{
		if (NodeSet.count(headB))
			return headB;
		headB = headB->next;	
	}
	return NULL;
}

//解法二:双指针 缺点:题目要求不改变原本链表结构,因此需要在输出结果前将改变的链表还原
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
	if (headA == NULL)
		return NULL;
	ListNode*TmpHeadA = headA;
	while (TmpHeadA->next != NULL)
		TmpHeadA = TmpHeadA->next;
	TmpHeadA->next = headA;
	if (headB == NULL || headB->next == NULL || headB->next->next == NULL){
		TmpHeadA->next = NULL;
		return NULL;
	}
	ListNode*SlowNode = headB->next;
	ListNode*FastNode = headB->next->next;
	while (FastNode->next != NULL && FastNode->next->next!=NULL && FastNode != SlowNode){
		SlowNode = SlowNode->next;
		FastNode = FastNode->next->next;
	}
	if (FastNode->next == NULL || FastNode->next->next == NULL){
		TmpHeadA->next = NULL;
		return NULL;
	}	
	else{
		ListNode*Tmp_HeadB = headB;
		while (Tmp_HeadB!=SlowNode)
		{
			Tmp_HeadB = Tmp_HeadB->next;
			SlowNode = SlowNode->next;
		}
		TmpHeadA->next = NULL;
		return SlowNode;
	}
}
//解法三:先计算两个链表的长度差,从对应点开始逐个比较
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
	ListNode*TmpHeadA = headA;
	ListNode*TmpHeadB = headB;
	int LenListA = 0;
	int LenListB = 0;
	for (; TmpHeadA != NULL; TmpHeadA = TmpHeadA->next, ++LenListA){}
	for (; TmpHeadB != NULL; TmpHeadB = TmpHeadB->next, ++LenListB){}
	
	int LenDifference = LenListA - LenListB;
	TmpHeadA = headA;
	TmpHeadB = headB;
	for (int i = 0; i < abs(LenDifference);++i)
	{
		if (LenDifference>0)
			TmpHeadA = TmpHeadA->next;
		else if (LenDifference < 0)
			TmpHeadB = TmpHeadB->next;
	}
	while (TmpHeadA!=NULL&&TmpHeadB!=NULL)
	{
		if (TmpHeadA == TmpHeadB)
			return TmpHeadA;
		TmpHeadA = TmpHeadA->next;
		TmpHeadB = TmpHeadB->next;
	}
	return NULL;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值