首页 > 代码库 > Intersection of Two Linked Lists

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的长度,然后从长的开始,直到走到两个一样长的地方,然后对比两个从哪里开始一样。

昨天经过和斯坦福小哥的对话之后觉得真的要好好关注代码质量了,然后虽然关注了也写了一个helper function,发现还是不够好。

改良前:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }
        int lenA = 0;
        int lenB = 0;
        ListNode a = headA;
        ListNode b = headB;
        while (a != null) {
            lenA++;
            a = a.next;
        }
        while (b != null) {
            lenB++;
            b = b.next;
        }
        ListNode result = null;
        if (lenA > lenB) {
            result = helper(headA, headB, lenA - lenB);
        } else {
            result = helper(headB, headA, lenB - lenA);
        }
        return result;
        
    }
    private ListNode helper(ListNode longer, ListNode shorter, int subtraction) {
        while (subtraction > 0) {
            longer = longer.next;
            subtraction--;
        }
        while (longer != null) {
            if (longer != shorter) {
                longer = longer.next;
                shorter = shorter.next;
            } else {
                return longer;
            }
        }
        return null;
    }
}

 改良后,好了点吧

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }
        int lenA = length(headA);
        int lenB = length(headB);

        ListNode result = null;
        if (lenA > lenB) {
            result = helper(headA, headB, lenA - lenB);
        } else {
            result = helper(headB, headA, lenB - lenA);
        }
        return result;
        
    }
    private ListNode helper(ListNode longer, ListNode shorter, int subtraction) {
        while (subtraction > 0) {
            longer = longer.next;
            subtraction--;
        }
        while (longer != null) {
            if (longer != shorter) {
                longer = longer.next;
                shorter = shorter.next;
            } else {
                return longer;
            }
        }
        return null;
    }
    private int length(ListNode head) {
        int len = 0;
        while (head != null) {
            len++;
            head = head.next;
        }
        return len;
    }
}

 

方法二:

利用快慢指针成环的原理,证明未完待续,以后再回顾下吧。。。linkedlist 环。

方法来自于此https://discuss.leetcode.com/topic/28067/java-solution-without-knowing-the-difference-in-len

证明在下面。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    //boundary check
    if(headA == null || headB == null) return null;
    
    ListNode a = headA;
    ListNode b = headB;
    
    //if a & b have different len, then we will stop the loop after second iteration
    while( a != b){
    	//for the end of first iteration, we just reset the pointer to the head of another linkedlist
        a = a == null? headB : a.next;
        b = b == null? headA : b.next;    
    }
    
    return a;
}

今天开始也用C++刷题啦,第一道题目

/**
 * 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;
        
    }
};

 对指针还是一知半解,慢慢来吧~

 

Intersection of Two Linked Lists