zoukankan      html  css  js  c++  java
  • 160. Intersection of Two Linked Lists

    https://leetcode.com/problems/intersection-of-two-linked-lists/#/description

    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.

    Sol 1:

    The key point is to find the overlap node, and when node A is not equal to node B, advance them and when either of them reaches the end, switch the head and continue the second traversal. There are two ways to get out the while A != B list :1) They meet. 2) They both hit the end = None. 

    (similar to the check loop in linked list) 

    # Definition for singly-linked list.
    class ListNode(object):
        def __init__(self, x):
            self.val = x
            self.next = None
    
    class Solution(object):
        def getIntersectionNode(self, headA, headB):
            """
            :type head1, head1: ListNode
            :rtype: ListNode
            """
            if (not headA) or (not headB):
                return None
            
            if headA and headB:
                A = headA
                B = headB
                while A != B:
                     # if either pointer hits the end, switch head and continue the second traversal, 
                     # if not hit the end, just move on to next
                    if A:
                        A = A.next 
                    else:
                        A = headB
                        
                    if B:
                        B = B.next
                    else:
                        B = headA
                return A  # only 2 ways to get out of the loop, they meet or the both hit the end=None
                
    # the idea is if you switch head, the possible difference between length would be countered. 
    # On the second traversal, they either hit or miss. 
    # if they meet, pa or pb would be the node we are looking for, 
    # if they didn't meet, they will hit the end at the same iteration, pa == pb == None, return either one of them is the same,None

    Sol 2:

    Traverse list A and list B once to get the length of list A and list B. Then reset current nodes as headA an headB. Advance the pointer on the longer list. While current A is not equal to current B, advance both list A and list B pointer, and after the while loop, we find the intersection where current node A equals to current node B, then return current A.

    O(n) time and O(1) space 

    # Definition for singly-linked list.
    class ListNode(object):
        def __init__(self, x):
            self.val = x
            self.next = None
    
    class Solution(object):
        def getIntersectionNode(self, headA, headB):
            """
            :type head1, head1: ListNode
            :rtype: ListNode
            """
            
            curA = headA
            curB = headB
            lenA = 0
            lenB = 0
            while curA:
                lenA += 1
                curA = curA.next
            while curB:
                lenB += 1
                curB = curB.next
            curA = headA
            curB = headB
            if lenA > lenB:
                for i in range(lenA - lenB):
                    curA = curA.next
            elif lenB > lenA:
                for i in range(lenB - lenA):
                    curB = curB.next
            while curB != curA:
                curB = curB.next
                curA = curA.next
            return curA
                    

    Sol 3:

    This problem could be considered as the derivation of linked list cycle.
    Let say there are two linked lists named l1 and l2. And h1 and t1 are the head and last nodes of l1 respectively, and h2 is the head node of l2.

    1. Concat h1 and t1
    2. Check whether there exists a cycle of linked list l2.
    3. Find that intersection if 2 is a truth.

    Before doing the above steps, there are two linked lists in the picture:
    enter image description here

    After step 1:
    enter image description here

    Then let's try to make the linked lists easier to understood.
    enter image description here
    Node 8 is what we want. We can use then solve it by finding the start node of the cycle like the problem "linked list cycle II"

    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """ 
        if not headA or not headB: return None
        
        p = headA
        while p.next:
            p = p.next
        mark = p
        #make a cycled list
        mark.next = headA
        
        rst = None
        p1 = headB
        p2 = headB
        while p1 and p2:
            p1 = p1.next
            p2 = p2.next
            if p2: p2 = p2.next
            if p1 == p2: break
    
        if p1 and p2 and p1 == p2:
            p1 = headB
            while p1 != p2:
                p1 = p1.next
                p2 = p2.next
            rst = p1
    
        #unmake the cycle
        mark.next = None

    return rst
  • 相关阅读:
    c#-全局键盘钩子
    C#-自动获取IP
    C#-自动获取IP
    C#-获取CPUID
    C#-获取CPUID
    手动添加导入表修改EXE功能
    安装全局消息钩子实现dll窗体程序注入
    手动添加导入表修改EXE功能
    虚拟桌面模拟查找点击自绘控件
    虚拟桌面模拟查找点击自绘控件
  • 原文地址:https://www.cnblogs.com/prmlab/p/6991875.html
Copyright © 2011-2022 走看看