LeetCode面试题 02.07. 链表相交【双指针】

LeetCode面试题 02.07. 链表相交

文章目录

    • LeetCode面试题 02.07. 链表相交
      • 1.题目
      • 2.思路
      • 3.代码实现

1.题目

LeetCode面试题 02.07. 链表相交【双指针】_第1张图片

2.思路

要注意的是:

1.如果两链表相交,从相交点到表尾都是相同的结点,即合二为一了。
2.这里的相交利用引用来判定!即结点的地址,而不是节点的数值!

思路:

1.统计两个链表长度,求差。
另:我在这里多考虑了一步,走到最后一个结点时判断下它们是否是同一个,即判断两个链表是否相交。
2.按照表尾对齐的形式,长链表的指针先走,走到和短链表的表头对齐为止。
3.两个指针同步走,若相交则停止。

3.代码实现

class Solution {
public:
 	ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
 		//1.特判头结点, 有一个空表确实没办法相交 
 		if(headA == NULL || headB == NULL) return NULL;//为空就没有?确实 
		
		//2.创建哑结点-方便指针统计长度时最后停在最后一个结点处 
 		ListNode* dummyA = new ListNode(-1);
 		dummyA->next = headA;
 		ListNode* dummyB = new ListNode(-1);
 		dummyB->next = headB;
        ListNode*a = dummyA;
        ListNode*b = dummyB;
        int sizeA = 0;int sizeB = 0;
        
        //3.统计长度  这个时候指针指向了最后一个结点,不是空!
       	while(a->next != NULL) 
       	{
       		a = a->next;
       		sizeA++;
		}
        while(b->next != NULL)
        {
        	b = b->next;
        	sizeB++;
		}
		delete dummyA;delete dummyB;//删了是个好习惯 
		
		//4.若最后一个节点位置相同,则是相交的。 分情况讨论 
		if(a == b) 
		{
			if(sizeA > sizeB)//A比B长 
			{
				//5.长度差 
				int cnt = sizeA - sizeB;
				ListNode* fast = headA;
				ListNode* slow = headB;
				
				//6.快指针先走,和慢指针的头对齐 
				while(cnt--) 
					fast = fast->next; 
				
				//7.同步走,遇到相交的起始点就返回 
				while(fast != slow)
				{
					fast = fast->next;
					slow = slow->next;
				 } 
				 ListNode *m = fast;
				 return m;
			}
			else //if(sizeA <= sizeB) B比A长或二者相等 
			//这里只能是else,编译器认为还有别的情况...
			{
				int cnt = sizeB - sizeA;
				ListNode* fast = headB;
				ListNode* slow = headA; 
				while(cnt--) 
					fast = fast->next; //和慢指针的头对齐
				while(fast != slow)
				{
					fast = fast->next;
					slow = slow->next;
				 } 
				 ListNode *m = fast;
				 return m;
			}
		}
		else return NULL;//不相交,直接返回 
    }
};

贴一段更精简的大佬的代码,省去了分情况讨论又产生的冗余代码,因为可以直接交换!就是会绕一点点。

 		curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            swap (lenA, lenB);//lenA存大值
            swap (curA, curB);//curA指长链表的头
        }
        // 求长度差
        int gap = lenA - lenB;
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != NULL) {
            if (curA == curB) {
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;

注意事项

有一个小tip:统计链表长度之类的想让指针停在最后一个节点处可以使用哑结点!
swap函数:交换各自地址处的值。比如swap(a,b);a,b是相同数据类型的变量。a,b的值分别赋给b,a。

你可能感兴趣的:(#,链表,链表,leetcode,算法)