1. 程式人生 > >Intersection of Two Linked Lists

Intersection of Two Linked Lists

use struct 關註 follow help per listnode 長度 section

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