输入两个无环的单链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的
示例1
输入:
{1,2,3},{4,5},{6,7}
返回值:
{6,7}
说明:
第一个参数{1,2,3}代表是第一个链表非公共部分,第二个参数{4,5}代表是第二个链表非公共部分,最后的{6,7}表示的是2个链表的公共部分
这3个参数最后在后台会组装成为2个两个无环的单链表,且是有公共节点的
示例2
输入:
{1},{2,3}{}
返回值:
{}
说明:
2个链表没有公共节点 ,返回null,后台打印{}
思路1:固定一端链表,另一端遍历
代码实现:
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1==null || pHead2==null)
return null;
ListNode head1 = null ;
while(pHead2!=null)
{
head1 = pHead1;
while(head1!=null)
{
if(head1.val==pHead2.val)
return head1;
head1 = head1.next;
}
pHead2 = pHead2.next;
}
return head1;
}
}
时间复杂度O(n^2),空间复杂度O(1)
思路2:双指针法
在没有公共节点的情况下,还是继续走,直到两个指针都为null了就退出循环
有公共节点 指针相等则退出,无公共节点 都指向null则退出,单个指针指向null表明指针走链表短的即将走下一条长的链表
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
//原链表判空
if(pHead1==null || pHead2==null)
return null;
ListNode head1 = pHead1;
ListNode head2 = pHead2;
while(head1!=head2&&(head1!=null||head2!=null))
{
if(head1==null)
head1=pHead2;
else
head1=head1.next;
if(head2==null)
head2=pHead1;
else
head2=head2.next;
}
return head1;
}
}
最好时间复杂度O(1), 最坏时间复杂度O(m+n)公共节点在最后一个节点,mn分别为两链表长度