Leetcode: Intersection of Two Linked Lists

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 linked lists have no intersection at all, return null.
    • The linked lists must retain their original structure after the function returns.
    • You may assume there are no cycles anywhere in the entire linked structure.
    • Your code should preferably run in O(n) time and use only O(1) memory.

分析:此题很有意思,联想到以前做过的linkedlist cycle II,我们不难想出reverse B然后将A和B连在一起,如果A和B有交点,那么A和B连在一起后一定有环,此时我们便可以用linked list cycle II的解法。代码如下:

 1 class Solution {
 2 public:
 3     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
 4         if(headA == NULL || headB == NULL) return NULL;
 5         if(headA == headB) return headA;
 6         
 7         ListNode *end = reverse(headB);//reverse B
 8         headB->next = headA;//construct a circle
 9         
10         ListNode *result = detectCycle(end);
11         headB->next = NULL;
12         headB = reverse(end);
13         
14         return result;
15     }
16     ListNode *reverse(ListNode *head){
17         if(head == NULL || head->next == NULL) return head;
18         ListNode dummy(-1);
19         dummy.next = head;
20         for(ListNode *pre = head, *p = head->next; p; p = pre->next){
21             pre->next = p->next;
22             p->next = dummy.next;
23             dummy.next = p;
24         }
25         return dummy.next;
26     }
27     
28     ListNode *detectCycle(ListNode *head) {
29         if(head == NULL || head->next == NULL) return NULL;
30         
31         ListNode *slow = head, *fast = head;
32         //find meeting point
33         while(slow->next && fast && fast->next){
34             slow = slow->next;
35             fast = fast->next->next;
36             if(slow == fast) break;
37         }
38         //no cycle
39         if(slow != fast) return NULL;
40         //find cycle beginning
41         fast = head;
42         while(fast != slow){
43             fast = fast->next;
44             slow = slow->next;
45         }
46         return fast;
47     }
48 };

此题还有另一种解法,这种题利用的都是几何距离关系,我们只要两个linked list到相交点距离的差值d,便可以很快找出相交点。当我们遍历完长度短的linked list时,长度长的linked list只访问到记录末尾距离为d。我们可以通过这点设计算法。假设两个linked list A和B, A的长度小于B的长度,我们分别用pA和pB遍历两个链表,当pA到达末尾时,将pA更新为链表B的头,然后接着遍历,知道pB达到末尾,此时将pB更新为链表A的头,继续遍历直到pA=pB。代码如下:

 1 class Solution {
 2 public:
 3     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
 4         if(headA == NULL || headB == NULL) return NULL;
 5         if(headA == headB) return headA;
 6         
 7         ListNode *pA = headA, *pB = headB;
 8         while(pA && pB){
 9             pA = pA->next;
10             pB = pB->next;
11         }
12         if(pA == NULL && pB == NULL){
13             pA = headA;
14             pB = headB;
15         }else if(pA == NULL){
16             pA = headB;
17             while(pB){
18                 pB = pB->next;
19                 pA = pA->next;
20             }
21             pB = headA;
22         }else{
23             pB = headA;
24             while(pA){
25                 pA = pA->next;
26                 pB = pB->next;
27             }
28             pA = headB;
29         }
30         while(pA && pB){
31                 if(pA == pB) return pA;
32                 pA = pA->next;
33                 pB = pB->next;
34             }
35             return NULL;
36     }
37 };

 

转载于:https://www.cnblogs.com/Kai-Xing/p/4148724.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值