1. 程式人生 > >LeetCode刷題EASY篇 Intersection of Two Linked Lists

LeetCode刷題EASY篇 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.

我的嘗試

兩個指標方法,發現有問題,我的程式碼在等長情況沒有問題,但是長度不一樣就不行了。

/**
 * 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) {
        while(headA!=null&&headB!=null){
            if(headA.val==headB.val){
                return headA;
            }
            headA=headA.next;
            headB=headB.next;  
        }
        return null;
    }
}

可以考慮利用hashmap儲存一個連結串列的資料,然後迴圈第二個連結串列,判斷是否有相同元素.測試通過

/**
 * 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) {
        Set set=new HashSet();
        while(headA!=null){
            set.add(headA.val); 
            headA=headA.next;
         }
        while(headB!=null){
            if(set.contains(headB.val)){
                return headB;
            }
            headB=headB.next;
        }
        return null;
    }
}

雖然測試通過,但是有問題,不要儲存val在set,因為可能不相交,但是val相同,所以應該儲存節點地址,修改如下:

/**
 * 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) {
        Set set=new HashSet();
        while(headA!=null){
            set.add(headA); 
            headA=headA.next;
         }
        while(headB!=null){
            if(set.contains(headB)){
                return headB;
            }
            headB=headB.next;
        }
        return null;
    }
}

其他解法

除了剛才的hashset方法,繼續研究兩個指標的方法,因為這是個重要的思路。看了其他高手的思路,發現如果長度不一樣,調整到同一個起點就ok。於是修改我的兩個指標程式碼如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    
    public int getLength(ListNode head){
        int length=0;
        while(head!=null){
            length++;
            head=head.next;
        }
        return length;
    }
    
    
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
       int lengthA=getLength(headA);
       int lengthB=getLength(headB);
       while(lengthA>lengthB){
           headA=headA.next;
           lengthA--;
       }
       while(lengthB>lengthA){
           headB=headB.next;
           lengthB--;
       }
        while(headA!=null&&headB!=null){
            if(headA==headB){
                return headA;  
            }
            headA=headA.next;
            headB=headB.next;
        }
        return headA;
    }
}