二、相交链表
本题给了我们两个单链表的头节点,让我们判断这两个链表是否相交,也就是说让我们判断这两个链表有没有相同的节点。
1.双指针
我们先定义两个指针让他们遍历这两个链表,分别计算出这两个链表的长度,然后计算出两个链表的长度之差,让较长链表的指针先走这个长度之差的步数,然后让另一个链表的指针和这个指针开始同步遍历这两个链表,这样就可以保证这两个指针在第一个相交的节点相遇,具体代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
struct ListNode *p, *q;
p = headA;
q = headB;
int p1 = 1,q1 = 1;
while(p->next)
{
p=p->next;
p1++;
}
while(q->next)
{
q=q->next;
q1++;
}
if(p != q)
{
return NULL;
}
int gap;
gap = p1 > q1 ? p1 - q1 : q1 - p1;
struct ListNode* pp,* qq;
pp = headA;
qq = headB;
if(p1>q1)
{
while(gap)
{
pp = pp->next;
gap--;
}
while(pp!=qq)
{
pp = pp->next;
qq = qq->next;
}
}
else
{
while(gap)
{
qq = qq->next;
gap--;
}
while(pp!=qq)
{
pp = pp->next;
qq = qq->next;
}
}
return pp;
}
复杂度分析
- 时间复杂度:O(n)。
- 空间复杂度:O(1)。
2.循环遍历
我们还可以循环遍历两个链表,依次比对每一个节点看他们是否相同,如果相同就说明存在相同节点,具体代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *p, *q;
p = headA;
q = headB;
while(p)
{
while(q)
{
if(p == q)
{
return p;
}
q = q->next;
}
q = headB;
p = p->next;
}
return p;
}
复杂度分析
- 时间复杂度:O(n * m)。
- 空间复杂度:O(1)。