160. Intersection of Two Linked Lists(注意方法!)

160. Intersection of Two Linked Lists(注意方法!)_第1张图片
image.png

http://bangbingsyb.blogspot.com/2014/11/leetcode-intersection-of-two-linked.html

找链表交界,很类似Linked List Cycle II那题,方法也是类似的双指针相遇法。分两步走:

  1. 如何判断两链表是否相交?
    两链表相交则他们必然有共同的尾节点。所以遍历两两链表,找到各自的尾节点,如果tailA!=tailB则一定不相交,反之则相交。
  1. 如何判断两链表相交的起始节点?
    在第1步判断相交时可以顺带计算两链表的长度lenA和lenB。让长的链表的head先走abs(lenA-lenB)步,然后和短链表的head一起走,直到两者相遇,即为要找的节点。

解法一 (两根指针):
先遍历一遍,看a和b的长度,然后长的那个先走l2 - l1 步,然后一起走。

/**
 * 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 l1 = 0, l2 = 0;
        ListNode * p1 = headA;
        ListNode * p2 = headB;
        while(p1){
            p1 = p1->next;
            l1++;
        }
        while(p2){
            p2 = p2->next;
            l2++;
        }
        p1 = headA;
        p2 = headB;
        if(l1 > l2){
            for(int i = 0; i < l1 - l2; i++){
                p1 = p1->next;
            }
        }
        else{
             for(int i = 0; i < l2 - l1; i++){
                p2 = p2->next;
            }
        }
        while(p1 && p2){
            if(p1 == p2){
                return p1;
            }
            else{
                p1 = p1->next;
                p2 = p2->next;
            }
        }
        return NULL;
    }
};

解法二:
https://zhuanlan.zhihu.com/p/32997648
You can prove that: say A length = a + c, B length = b + c, after switching pointer, pointer A will move another b + c steps, pointer B will move a + c more steps, since a + c + b + c = b + c + a + c, it does not matter what value c is. Pointer A and B must meet after a + c + b (b + c + a) steps. If c == 0, they meet at NULL.
当p1走完时,接着head2,当p2走完是,接着head1,设l1长度(a+c)
l2长度(b+c),所以换完pointer之后,因为(a+c+b+c) = (b+c+a+c);
所以如果不管有没有交叉,最后都在C;如果没有交叉,为NULL;
如果有交叉,那么在前退C步的时候,相遇,即(a+c+b) = (b+c+a)

/**
 * 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) {
        if(headA == NULL || headB == NULL){
            return NULL;
        }
        ListNode *p1 = headA;
        ListNode *p2 = headB;
        while(p1 != p2){
            p1 = p1 == NULL ? headB : p1->next;
            p2 = p2 == NULL ? headA : p2->next;
        }
        return p1;
    }
};

解法三:哈希
用哈希表也可以过!!!!!找到了新大陆!!!!

/**
 * 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) {
        map hash_map;
        ListNode * p1 = headA, *p2 = headB;
        while(p1){
            hash_map[p1] = 1;
            p1 = p1->next;
        }
        while(p2){
            if(hash_map[p2] == 1){
                return p2;
            }
            p2 = p2->next;
        }
        return NULL;
    }
};

你可能感兴趣的:(160. Intersection of Two Linked Lists(注意方法!))