链表相交
leetcode题目:160,寻找两个链表的相交节点。
headA:a1–>a2–>a3–>a4–c1–>c2,headB:b1–>b2–>c1–>c2,则返回指向节点c1的指针。
-
难点:假设ai节点为两个链表的节点,则从ai节点开始,链表A与链表B的每一个节点都重合,所以可以从两个链表的最后一个节点开始向前比较,但是链表有不能反向遍历的特点。
-
突破口:假设链表A的长度为m,链表B的长度为n(m>n),显然链表A的1,2,…,m-n个节点不可能是交点,否则从交点起的两个链表重合部分的长度都不一样。
所以只需要从链表A的第m-n+1节点我位置处,依次比较链表节点的下一个节点指针,若相等,说明指向了同一个节点,即指向了交点,则返回。
寻找指向链表第i(i = 1, 2, 3, 4, …)个节点的指针方法:
ListNode *cur;
while(--i)
{
cur = cur -> next;
}
//如果i = 1,则不执行循环体,cur = head,head指向第一个节点
//i = 2, 则执行1次循环体,最后 cur = head -> next, head指向第一个节点,next指向第二个节点
完整程序
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int m = 0, n = 0;
ListNode *cur = headA, *longH = headA, *shortH = headB, *curS;
while(cur)
{
m++;
cur = cur ->next;
}
cur = headB;
while(cur)
{
n ++;
cur = cur -> next;
}
if (m < n)
{
longH = headB;
shortH = headA;
int tmp = n;
n = m;
m = tmp;
}
//寻找指向较长链表第m - n + 1的指针
cur = longH;
int start = m - n + 1;
while(--start) cur = cur -> next;
curS = shortH;
while((cur != curS))
{
cur = cur -> next;
curS = curS -> next;
}
if(cur == NULL) return NULL;
else return cur;
}
};