找到两个链表的第一个公共节点 37

?
?

引言

?
?

这个问题一种常想到的方法就是两层循环遍历,外层循环遍历链表A,对A中每个节点,遍历链表B,如果在B中找到,说明这个节点是第一个公共节点,但是这样的方法时间复杂为mn,一般是不允采用的

?
?

分析问题

?
?

所以我们需要分析更深层次的问题,找到其中的规律,我们如果动手画一下一般的链表图就能够发现两个链表的第一个公共节点之后的样子一定是如下表示(由此可以发现有时候动手是很重要的)

?
?

?
?

可以发现两个链表在第一个节点重合之后不会再分开了

?
?

简单多说一句不会分开的原因,因为单向链表的节点只有一个nextNode指向下一个节点,那么如果该节点重合了,那么后面的节点一定是同一个

?
?

如果直观点对这个图形进行解释就是两个链表重合之后呈现一个Y型而不是一个X型

?
?

解决问题

?
?

一般这种问题要用两个类似指针的东西,一个先走,一个后走

?
?

所以我们先遍历找到两个链表的长度m和n,如果m大,m比n大多少,比如说k,那么先让m先走k步,然后n和m再一起走

?
?

ListNode findFirstCommonNode(ListNode root1, ListNode root2) {

ListNode resultNode = null;

int length1 = getLength(root1);

int length2 = getLength(root2);

?
?

ListNode LongList;

ListNode ShortList;

int steps = 0;

if (length1 > length2) {

LongList = root1;

ShortList = root2;

steps = length1 - length2;

} else {

LongList = root2;

ShortList = root1;

steps = length2 - length1;

}

?
?

for (int i = 0; i < steps; i++) {

LongList = LongList.nextNode;

}

while (LongList != null && ShortList != null && LongList != ShortList) {

LongList = LongList.nextNode;

ShortList = ShortList.nextNode;

}

?
?

resultNode = LongList;

return resultNode;

?
?

}

?
?

测试代码

?
?

public static void main(String[] args) {

ListNode head1=new ListNode();

ListNode second1=new ListNode();

ListNode third1=new ListNode();

ListNode forth1=new ListNode();

ListNode fifth1=new ListNode();

ListNode head2=new ListNode();

ListNode second2=new ListNode();

ListNode third2=new ListNode();

ListNode forth2=new ListNode();

head1.nextNode=second1;????????

second1.nextNode=third1;

third1.nextNode=forth1;

forth1.nextNode=fifth1;

head2.nextNode=second2;

second2.nextNode=forth1;

third2.nextNode=fifth1;

head1.data=1;

second1.data=2;

third1.data=3;

forth1.data=6;

fifth1.data=7;

head2.data=4;

second2.data=5;

third2.data=6;

forth2.data=7;

FindFirstCommonNode test=new FindFirstCommonNode();

System.out.println(test.findFirstCommonNode(head1, head2).data);

}

时间: 2024-10-05 04:55:17

找到两个链表的第一个公共节点 37的相关文章

剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)

思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到链表的长度风别为,len1和len2,求出两者的差值dif,然后现在长的链表上面走dif步,然后同步走剩下的节点,当就可以找到第一个公共节点了. public ListNode findFirstCommonNode(ListNode pHead1,ListNode pHead2){ if(pHea

经典算法学习——打印两个链表的第一个公共节点

求链表的公共节点是一道很经典的算法题,并不是很难.我们需要知道的是,一旦两个链表有一个公共节点的话,那么这两个链表的形状就是一个"Y"型.也就是说,自公共节点之后的所有节点都是一样的.如下: 其实只要看了这幅图,实现就很简单了.首先我们分别遍历两个链表,分别得出他们的长度L1,L2.然后在查找公共节点时,先在长的那个链表中走|L1-L2|步,然后两个链表同时向后进行同步遍历,每走一步时,就判断后面那个节点是否相同.若相同,则找到该第一个公共节点.完整代码上传至 https://gith

37 - 两个链表的第一个公共节点

题目描述: 输入两个链表,找出它们的第一个公共结点. 如:第一个公共节点为值为 6 的节点. 相关题型:在二叉树中找出两个节点的最低公共祖父节点.使用的算法是:找出根到2个节点的路径,然后从根遍历,当最后一个相同的节点,即为最低公共祖父节点. 思路一: 在本题中,如果我们能从最后 1 个节点(如bst中的根) 向前遍历,则很容易找出第一个公共节点,但是单链表只能从前向后遍历.而给定从前到后,如何得到从后向前,可以想到使用先进后出的栈. 因此我们可以用2个栈存储2个链表的节点,然后从栈顶开始逐个比

【剑指offer】52、两个链表的第一个公共节点

题目 输入两个链表,找出它们的第一个公共结点. 思路一 因为是反向找,所以会想到用栈.将两个链表都压入两个栈,然后反向弹出,找出第一个公共节点.思路很简单 class Solution { public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { stack<ListNode*> s1, s2; if (pHead1 == nullptr || pHead2 == nullptr) return n

36.两个链表的第一个公共节点。

题目描述: ??输入两个链表,找出它们的第一个公共结点. 思路分析: ??由于链表的指针只能指向一个节点,所以两个链表相交后,后面的部分完全一样.所以我们的解题思路就是先求出两个链表的长度,设置俩个指针分别指向两个链表的头部.指向较长链表的指针先走两个链表长度差步,然后两个指针同时开始走,当两个指针指向同一个节点时,这个节点就是第一个公共节点. 代码: /* public class ListNode { int val; ListNode next = null; ListNode(int v

两个链表的第一个公共节点

已知有两个链表,他们可能相交于某一点,求出该点. 方法1.对于第一个链表,每访问一个节点,对该节点做标记.访问第二个链表,如果该元素已经访问,则第一个这样的元素就是所求点. 由于两个链表都访问了一遍,因此时间复杂度O(m+n),空间复杂度O(m)或O(n) 方法2.我们定义节点的距离为节点到链表开始所经过的节点数.如果两个链表长度相同,则相交节点其在两个链表上的距离一定相等.对于长度不同的两个链表,我们可以采用对齐的方式,使其向长度短的链表对齐.这样就可以应用上面的思路.具体算法如下: [cpp

判断两个链表是否相交;查找两个链表的第一个公共节点

问题一:(引用编程之美)如果两个链表相交,则尾节点一定是公共的 问题二: 1 int listLength(node* list){ 2 int length=0; 3 while(list!=NULL){ 4 length++; 5 list=list->next; 6 } 7 return length; 8 } 9 // 10 node* firstComNode(node* list1,node* list2){ 11 int n1=listLength(list1); 12 int n

面试题52:两个链表的第一个公共节点

# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def FindFirstCommonNode(self, pHead1, pHead2): # write code here #参数1:较短的链表 #参数2:较长的链表 #参数3:较短的链表头 #参数4:较长的链表头 def findequal(shortpoin

(LeetCode)两个链表的第一个公共节点

LeetCode上面的题目例如以下: 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 lin