Ejemplo n.º 1
0
def overlapping_lists(l0, l1):
    root0, root1 = has_cycle(l0), has_cycle(l1)
    if not root0 and not root1:
        return overlapping_no_cycle_lists(l0, l1)
    elif (not root0 and root1) or (root0 and not root1):
        return None
    # both lists have cycles: (1) disjoint cycles (2) starting nodes in cycles are the same
    # (3) starting nodes in cycles are different
    temp = root1
    while True:
        temp = temp.next
        if temp is root0 or temp is root1:
            break
    if temp is not root0:
        return None  # disjoint cycles

    def distance(s, t):
        dist = 0
        while s is not t:
            dist += 1
            s = s.next
        return dist

    length0, length1 = distance(l0, root0), distance(l1, root1)
    if length0 > length1:
        l0, l1 = l1, l0
        root0, root1 = root1, root0
    for i in range(abs(length0 - length1)):
        l1 = l1.next
    while l0 is not l1 and l0 is not root0 and l1 is not root1:
        l0, l1 = l0.next, l1.next
    return l0 if l0 is l1 else root0
def overlapping_lists(l0, l1):
    root0, root1 = has_cycle(l0), has_cycle(l1)

    if not root0 and not root1:
        return overlapping_no_cycle_lists(l0, l1)
    elif (root0 and not root1) or (not root0 and root1):
        return None

    temp = root1
    while True:
        temp = temp.next
        if temp is root0 or temp is root1:
            break

    if temp is not root0:
        return None

    def distance(a, b):
        dis = 0
        while a is not b:
            a = a.next
            dis += 1
        return dis

    stem0_length, stem1_length = distance(l0, root0), distance(l1, root1)
    if stem0_length > stem1_length:
        l1, l0 = l0, l1
        root0, root1 = root1, root0
    for _ in range(abs(stem0_length - stem1_length)):
        l1 = l1.next
    while l0 is not l1 and l0 is not root0 and l1 is not root1:
        l0, l1 = l0.next, l1.next

    return l0 if l0 is l1 else root0
Ejemplo n.º 3
0
def overlapping_lists(l0, l1):

    # Store the start of cycle if any.
    root0, root1 = has_cycle(l0), has_cycle(l1)

    if not root0 and not root1:
        # Both lists don't have cycles.
        return overlapping_no_cycle_lists(l0, l1)
    elif (root0 and not root1) or (not root0 and root1):
        # One list has cycle, one list has no cycle.
        return None
    # Both lists have cycles.
    temp = root1
    while True:
        temp = temp.next
        if temp is root0 or temp is root1:
            break

    # l0 and l1 do not end in the same cycle.
    if temp is not root0:
        return None  # Cycles are disjoint.

    # Calculates the distance between a and b.
    def distance(a, b):
        dis = 0
        while a is not b:
            a = a.next
            dis += 1
        return dis

    # l0 and l1 end in the same cycle, locate the overlapping node if they
    # first overlap before cycle starts.
    stem0_length, stem1_length = distance(l0, root0), distance(l1, root1)
    if stem0_length > stem1_length:
        l1, l0 = l0, l1
        root0, root1 = root1, root0
    for _ in range(abs(stem0_length - stem1_length)):
        l1 = l1.next
    while l0 is not l1 and l0 is not root0 and l1 is not root1:
        l0, l1 = l0.next, l1.next

    # If l0 == l1 before reaching root0, it means the overlap first occurs
    # before the cycle starts; otherwise, the first overlapping node is not
    # unique, we can return any node on the cycle.
    return l0 if l0 is l1 else root0
Ejemplo n.º 4
0
def overlapping_lists(l0, l1):
    # TODO - you fill in here.
    root0 = has_cycle(l0)
    root1 = has_cycle(l1)

    if not root0 and not root1:
        return overlapping_no_cycle_lists(l0, l1)
    elif (root0 and not root1) or (root1 and not root0):
        return None

    runner = root1
    while True:
        runner = runner.next
        if runner is root0 or runner is root1:
            break

    if runner is not root0:
        return None

    def distance(a, b):
        dis = 0
        while a is not b:
            a = a.next
            dis += 1
        return dis

    stem_length0 = distance(l0, root0)
    stem_length1 = distance(l1, root1)

    # make sure that root0 comes first
    if stem_length0 > stem_length1:
        l0, l1 = l1, l0
        root0, root1 = root1, root0

    for _ in range(abs(stem_length0 - stem_length1)):
        l1 = l1.next

    while l0 is not l1 and l0 is not root0 and l1 is not root1:
        l0 = l0.next
        l1 = l1.next

    if l0 is l1:
        return l0
    else:
        return root1
Ejemplo n.º 5
0
def overlapping_lists(l0: ListNode, l1: ListNode) -> Optional[ListNode]:
    # Store the start of cycle if any.
    root0, root1 = has_cycle(l0), has_cycle(l1)

    if not root0 and not root1:
        # Both lists don't have cycles.
        return overlapping_no_cycle_lists(l0, l1)
    elif (root0 and not root1) or (not root0 and root1):
        # One list has cycle, one list has no cycle.
        return None
    # Both lists have cycles.
    temp = root1
    while temp:
        temp = temp.next
        if temp is root0 or temp is root1:
            break

    return root1 if temp is root0 else None
Ejemplo n.º 6
0
def overlapping_lists(l0: ListNode, l1: ListNode) -> Optional[ListNode]:
    # TODO - you fill in here.
    t0, t1 = has_cycle(l0), has_cycle(l1)

    #neither list is cyclic
    if not t0 and not t1:
        return overlapping_no_cycle_lists(l1, l0)
    #one list is cyclic
    elif (t0 and not t1) or (t1 and not t0):
        return None

    #both lists are cyclic
    temp = t1
    while temp:
        temp = temp.next
        if temp is t0 or temp is t1:
            break

    return t1 if temp is t0 else None
Ejemplo n.º 7
0
def overlapping_lists(l0: ListNode, l1: ListNode) -> Optional[ListNode]:
    def cycle_length(start):
        x, length = start, 0
        while True:
            length += 1
            x = x.next
            if x is start:
                return length

    x0, x1 = has_cycle(l0), has_cycle(l1)
    n_cyclic = (x0 is not None) + (x1 is not None)

    if n_cyclic == 0:
        return overlapping_no_cycle_lists(l0, l1)
    elif n_cyclic == 1:
        return None

    for _ in range(cycle_length(x0)):
        if x0 is x1:
            return x0
        x0 = x0.next

    return None