一、题目:两个单链表相交的一系列问题
思路:
1、首先分别判断两个链表是否有环。如果一个有环,一个无环,则表明肯定不相交。
思路:设置两个指针,一个慢slow【每次只走一步】,一个快fast【每次走两步】,如果快的走完全程,即走到None,则表示没有环,如果两个指针一直走下去,且存在slow = fast 相等的时候,表明有环。一个发现:
两者相等的时候是头结点,可以试着证明以下:
2、分为两个问题:
(1)两个链表都无环,求相交点或者不相交。
(2)两个链表都有环,求相交点或者不相交。
1、判断链表是否有环的代码:
class Node: def __init__(self,value): self.value = value self.next = None def getLoopNode(head): if not head or not head.next or not head.next.next: return None slow = head.next fast = head.next.next while slow != fast: if not fast.next or fast.next.next == None: return None slow = slow.next fast = fast.next.next fast = head while slow != fast: slow = slow.next fast = fast.next return slow head = Node(1) p = head for i in range(4): p.next = Node(i) p = p.next # p.next = head res = getLoopNode(head)
2、无环链表的交点代码:
步骤1:获得两个链表的长度len1和len2,以及两个链表的尾部end1和end2。
步骤2:如果两个尾部end1和end2不等,则表明两个链表是没有交点的。
步骤3:如果end1 == end2,则比较两个长度len1和len2,将较长的链表先走 abs(len2-len1)步,然后将两个链表置于同一起点,直到两个链表走到相同的交点。
class Node: def __init__(self,value): self.value = value self.next = None def getLoopNode(head1,head2): if not head1 or not head2: return None #len1,len2用来记录两个链表长度 len1 , len2 = 0,0 #end1,end2用来表示两个链表结尾 end1 , end2 = head1 , head2 #获得链表1结尾,以及长度 while end1: len1 += 1 end1 = end1.next #获得链表2结尾以及长度 while end2: len2 += 1 end2 = end2.next #如果两个结尾不一样,则表明两个链表不相交 if end1 != end2: return None # 比较两个链表的长度 p1 = head1 if len1 > len2 else head2 p2 = head2 if p1 == head1 else head1 #然后将较长的先走abs(len2-len2)步,让两个链表同一起点 for i in range(abs(len2-len1)): p1 = p1.next #两个链表同时走,直到两个相等即为相交点 while p1 != p2: p1 = p1.next p2 = p2.next return p1 head1 = Node(1) p = head1 for i in range(2,5): p.next = Node(i) p = p.next head2 = Node(4) p = head1 head2.next = p.next.next res = getLoopNode(head1,head2)
3、有环链表的交点思路:
上面的求解和无环类似。
二、链表相加
class ListNode: def __init__(self, x): self.val = x self.next = None def addLists(l1, l2): # write your code here if l1 is None: return l2 if l2 is None: return l1 head1 = l1 head2 = l2 flag = 0 while head1.next is not None or head2.next is not None: # 存在某一链表next为空时,构造next.val = 0,不影响加法结果 if head1.next is None: head1.next = ListNode(0) if head2.next is None: head2.next = ListNode(0) sumNum = head1.val + head2.val if sumNum >= 10: head1.val = sumNum%10 flag = 1 head1.next.val += 1 else: head1.val = sumNum flag = 0 head1 = head1.next head2 = head2.next else: # 链表末尾时,单独处理,其和大于10时,追加节点 head1.val = head1.val + head2.val if head1.val >= 10: head1.val = head1.val%10 head1.next = ListNode(1) return l1 a = list(map(int,input().split())); b = list(map(int,input().split())); a = a[::-1]; b = b[::-1]; //创建列表 l1 = ListNode(a[0]); p1 = l1; l2 = ListNode(b[0]); p2 = l2; for i in range(1,len(a)): p1.next = ListNode(a[i]); p1 = p1.next; for i in range(1,len(b)): p2.next = ListNode(b[i]); p2 = p2.next; //列表相加 list_ = addLists(l1, l2); //结果逆序 res = [] while list_: res.append(list_.val); list_ = list_.next; res = list(map(str,res[::-1])) print(" ".join(res))