python算法-018判断两个链表是否相交(首尾相接\HashSet)

我发现边的写python的人太少了。学算法的又得有基础,所以很尴尬,我就写的简略一点了,而且今天的题确实不难。。

因为团队要做小程序,做web应用开发,所以今天接触了JS,JavaScript真是一种神奇的语言.....

我现在还不明白小程序到底是这个啥。。

题目:给定链表head1和head2,判断他们是否相交。相交的链表如下:

给定链表 Head1->1->1->3->3->5->7->7->8
                        ^
                        /
                        /
        Head2->1->1->3->3

两种方法:

  • 首尾相接法:将head1的尾部接到head2的头部,如果两个链表相交,则会在head1的尾部形成环,或者说,head2就是一个环。判断是否有环即可。

  • HashSet法:建立一个Hashset,先遍历head1,并将链表的节点的Next域存储在hashset表中,然后遍历head2中的链表,并将当前的节点的Next域与hashset表中的值作比较,如果存在相同的值,则表明两条链表相交。

上面的两种方法,相比之下第二种的效率更高!
下面先实现两个相交的链表:

import random
class LNode:
    def __init__(self,arg):
        self.data=arg
        self.next=None
def creatLink(x):
    i = 1
    head = LNode(None)
    tmp = None
    cur = head
    while i <= x:
        n = random.randint(1, 9)
        tmp = LNode(n)
        cur.next = tmp
        cur = tmp
        i += 1
    return head

head1=creatLink(7)
head2=creatLink(5)
cur=head2.next
while cur.next is not None:
    cur=cur.next
q = head1.next.next.next
#三分之一的概率出先相交
if random.randint(0,2)==1:
    cur.next=q

下面代码实现两种方法:
首尾相交法:先首尾相交,在判断是否存在环

def creatannulation(head1,head2):
    if head1 is None or head2 is None or head1.next is None or head2.next is None:
        return None
    last=None#用于指向链表最后一个节点
    head1first=None#用于指向head2的第一个节点
    last=head1.next
    head1first=head2.next
    while last.next is not None:
        last=last.next
    last.next=head1first
    return head1
def judgeAnnulation(head):
    if head.next is None or head.next is None:
        return None
    slow=head.next
    fast=head.next.next
    while fast.next is not None:
        if slow.next==fast.next:
            return 0
        slow=slow.next
        fast=fast.next.next
    return 1

hashset法:

def JudgeX(head1,head2):
    if head1 is None or head2 is None or head1.next is None or head2.next is None:
        return None
    hashset=set()#存储链表的Next域
    hashset.clear()
    p=None#用来遍历链表
    p=head1.next
    while p.next is not None:
        hashset.add(p.next)
        p=p.next
    p=head2.next
    while p is not None:
        if p.next in hashset:
            return 1#香蕉
        p=p.next
    return 0#不香蕉

主函数:

    head1=creatLink(7)
    head2=creatLink(5)
    q = head1.next.next.next
    print("q->", q.data)
    cur=head2.next
    while cur.next is not None:
        cur=cur.next
    if random.randint(0,2)==1:
        cur.next=q
    print("head1:")
    cur = head1.next
    while cur != None:
        print(cur.data)
        cur = cur.next

    print("head2:")
    cur = head2.next
    while cur != None:
        print(cur.data)
        cur = cur.next
    if JudgeX(head1,head2)==1:
        print("两个链表相交")
    elif JudgeX(head1,head2)==0:
        print("两个链表不相交")

运行结果:


相交

不相交

全部代码:

import random
class LNode:
    def __init__(self,arg):
        self.data=arg
        self.next=None

"""
题目描述:
给定链表 Head1->1->1->3->3->5->7->7->8
                        ^
                        /
                        /
        Head2->1->1->3->3
判断两个链表是否交叉,
要求:
方法:建立一个Hashset,先遍历head1,
并将链表的节点的Next域存储在hashset表中,
然后遍历head2中的链表,并将当前的节点的Next域与hashset表中
的值作比较,如果存在相同的值,则表明两条链表相交
"""
def creatLink(x):
    i = 1
    head = LNode(None)
    tmp = None
    cur = head
    while i <= x:
        n = random.randint(1, 9)
        tmp = LNode(n)
        cur.next = tmp
        cur = tmp
        i += 1
    return head
def JudgeX(head1,head2):
    if head1 is None or head2 is None or head1.next is None or head2.next is None:
        return None
    hashset=set()#存储链表的Next域
    hashset.clear()
    p=None#用来遍历链表
    p=head1.next
    while p.next is not None:
        hashset.add(p.next)
        p=p.next
    p=head2.next
    while p is not None:
        if p.next in hashset:
            return 1#香蕉
        p=p.next
    return 0#不香蕉


def creatannulation(head1,head2):
    if head1 is None or head2 is None or \
head1.next is None or head2.next is None:
        return None
    last=None#用于指向链表最后一个节点
    head1first=None#用于指向head2的第一个节点
    last=head1.next
    head1first=head2.next
    while last.next is not None:
        last=last.next
    last.next=head1first
    return head1
def judgeAnnulation(head):
    if head.next is None or head.next is None:
        return None
    slow=head.next
    fast=head.next.next
    while fast.next is not None:
        if slow.next==fast.next:
            return 1
        slow=slow.next
        fast=fast.next.next
    return 0


if __name__ == '__main__':
    head1=creatLink(7)
    head2=creatLink(5)
    q = head1.next.next.next
    print("q->", q.data)
    cur=head2.next
    while cur.next is not None:
        cur=cur.next
    if random.randint(0,2)==1:
        cur.next=q
    print("head1:")
    cur = head1.next
    while cur != None:
        print(cur.data)
        cur = cur.next

    print("head2:")
    cur = head2.next
    while cur != None:
        print(cur.data)
        cur = cur.next
    print("hashset:")
    if JudgeX(head1,head2)==1:
        print("两个链表相交")
    elif JudgeX(head1,head2)==0:
        print("两个链表不相交")
    print("首尾相接")
    head=creatannulation(head1,head2)
    buer=judgeAnnulation(head)
    if buer==1:
        print("两个链表相交")
    elif buer==0:
        print("两个链表不相交")

好了,话不多说,加油!

你可能感兴趣的:(python算法-018判断两个链表是否相交(首尾相接\HashSet))