Intersection of Two Linked Lists
阿新 • • 發佈:2017-06-04
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