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; } };
对指针还是一知半解,慢慢来吧~