1.11判斷兩個無環單鏈表是否相交

判斷兩個無環單鏈表是否交叉

題目描述:


如上圖,這兩個鏈表相交於結點5,要求判斷兩個鏈表是否相交,若是相交,找出相交處的結點。node

解題思路:

方法一:Hash 法

如上圖所示,若是兩個鏈表相交,那麼它們必定會有公共的結點,因爲結點的地址或引用能夠做爲結點的惟一標識,所以,能夠經過判斷兩個鏈表中的結點是否有相同的地址或引用來判斷鏈表是否相交。指針

方法二:首尾相接法

將這兩個鏈表首尾相連(例如把鏈表headl尾結點連接到head2的頭指針),而後檢測這個鏈表是否存在環,若是存在,則兩個鏈表相交,而環入口結點即爲相交的結點。
code

方法三:尾結點法

若是兩個鏈表相交,那麼兩個鏈表從相交點到鏈表結束都是相同的結點,必然是Y字形,因此,判斷兩個鏈表的最後一個結點是否是相同便可。即先遍歷一個鏈表,直到尾部,再遍歷另一個鏈表,若是也能夠走到一樣的結尾點,則兩個鏈表相交,這時記下兩個鏈衰的長度c1,c2,再遍歷一次,長鏈表結點先出發前進|c1-c2|步,以後兩個鏈表同時前進,每次一步,相遇的第一點即爲兩個鏈表相交的第一個點。blog

代碼實現:

# -*-coding:utf-8-*- 
"""
@Author  : 圖南
@Software: PyCharm
@Time    : 2019/9/7 21:24
"""


# 尾節點法
class Node:
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next


def printLink(head):
    if head is None or head.next is None:
        return
    cur = head.next
    while cur is not None:
        print(cur.data, end=' ')
        cur = cur.next
    print()

# 構造相交鏈表
def conInterLink(n1, n2, k):
    k = int(k)
    nums1 = list(map(int, n1.split(' ')))
    nums2 = list(map(int, n2.split(' ')))
    if len(nums1) > len(nums2):
        return conLink(nums1, nums2, k)
    else:
        head2, head1 = conLink(nums2, nums1, k)
        return head1, head2


def conLink(nums1, nums2, k):
    head1 = Node()
    head2 = Node()
    cur1 = head1
    cur2 = head2
    f = None
    for i in range(1, len(nums1) + 1):
        node = Node(nums1[i - 1])
        cur1.next = node
        cur1 = node
        if i == k:
            f = cur1
    for i in range(1, len(nums2) + 1):
        node = Node(nums2[i - 1])
        cur2.next = node
        cur2 = node
    cur2.next = f
    return head1, head2

# 遍歷兩個鏈表並計算長度
def traLink(head):
    cur = head.next
    count = 1
    while cur.next is not None:
        cur = cur.next
        count += 1
    return cur, count

# 長鏈表先走k步
def beforLink(head, k):
    cur = head.next
    for i in range(k):
        cur = cur.next
    return cur

# 獲取相交點
def getPoint(head1, head2, count1, count2):
    cur1 = beforLink(head1, count1 - count2)
    cur2 = head2.next
    while cur1 is not None:
        if cur1 is cur2:
            return cur1.data
        cur1 = cur1.next
        cur2 = cur2.next


def findInterPoint(head1, head2):
    cur1, count1 = traLink(head1)
    cur2, count2 = traLink(head2)
    if cur1 is cur2:
        print("兩個鏈表相交!")
        if count1 > count2:
            return getPoint(head1, head2, count1, count2)
        else:
            return getPoint(head2, head1, count2, count1)
    else:
        return "兩個鏈表不相交!"

if __name__ == '__main__':
    n1 = input('Link1:')
    n2 = input('Link2:')
    k = input('相交點:')
    head1, head2 = conInterLink(n1, n2, k)
    printLink(head1)
    printLink(head2)
    print(findInterPoint(head1, head2))

運行結果:

鏈表一長度大於鏈表二:

鏈表二長度大於鏈表一:

兩鏈表不相交:

兩鏈表相交在第一個節點:
utf-8

引伸:若是單鏈表有環,如何判斷兩個鏈表是否相交

  1. 若是一個單鏈表有環,另一個沒環,那麼它們確定不相交。
  2. 若是兩個單鏈表都有環而且相交,那麼這兩個鏈表必定共享這個環。以下圖

  3. 判斷兩個有環的鏈表是否相交的方法爲:首先找到鏈表headl中環的入口點pl,而後遍歷鏈表head2,判斷鏈表中是否包含結點 pl,若是包含,則這兩個鏈表相交,不然不相交。
  4. 找相交點的方法爲:把結點pl看做兩個鏈表的尾結點,這樣就能夠把問題轉換爲求兩個無環鏈表相交點的問題。
相關文章
相關標籤/搜索