劍指offer——python【第16題】合並兩個有序鏈表


題目描述

將兩個有序鏈表合並為一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 

示例:

輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4

思路

有兩種方法,一個不用遞歸,另一個用遞歸

解題

一、不用遞歸的解法

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if l1 is None and l2 is None:
            return None
        new_list = ListNode(0)
        pre = new_list
        while l1 is not None and l2 is not None:
            if l1.val < l2.val:
                pre.next = l1
                l1 = l1.next
            else:
                pre.next = l2
                l2 = l2.next
            pre = pre.next
        if l1 is not None:
            pre.next = l1
        else:
            pre.next = l2
        return new_list.next

首先,因為之前不是很懂python里鏈表這種表示方法,經過一些代碼實操,現在明白了,在第一個ListNode這種類表示方法里,如果只有__init__這個定義函數,那這個類的實例化對象只能表示一個節點,它雖然具有初始節點值,也有.next這個定義,但沒有接下來其他類函數去定義節點關系,那它就只能表示一個節點。仔細看下面

head1 = ListNode(2)
n1 = ListNode(3)
n2 = ListNode(4)
n3 = ListNode(9)
head1.next = n1
n1.next = n2
n2.next = n3

head2 = ListNode(3)
m1 = ListNode(5)
m2 = ListNode(7)
m3 = ListNode(8)
head2.next = m1
m1.next = m2
m2.next = m3
while head1:
    print(head1.val)
    head1 = head1.next
while head2:
    print(head2.val)
    head2 = head2.next

#2
3
4
9
3
5
7
8

第一段代碼其實定義了兩個有序鏈表,分別是2-->3-->4-->9和3-->5-->7-->8,因為ListNode類的實例化對象只是節點,所以上面所做的就是把分別定義四個節點,然后通過python里面的這種"="賦值方法把節點依次傳遞下去,比如head1的下一個節點是n1,這樣就把兩個鏈表造好了(當然在完整的單鏈表構造中,有append、insert、pop、appendleft等方法)

我們再回到解法里面,l1和l2其實是兩個鏈表的頭節點,當他們都不存在的時候,那就直接返回None了,沒毛病;然后,

new_list = ListNode(0)這個意思是構造一個初始節點,也就是新鏈表的初始節點,其實可以把new_list理解為根節點;接着下一步是pre = new_list,這一步很關鍵,因為如果不賦值的話,讓new_list自身去不斷next傳遞節點關系,
那根節點就找不到了,所以需要先把new_list保存,接着進行一個while循環,條件是l1和l2這兩個節點都不能為空,也就是說在兩個鏈表長度范圍之內遍歷,當l1(初始是鏈表1的頭節點)的值小於l2的值,那就把pre的指向l1,其實也就是new_list
指向了l1,下面的步驟應該不難理解了;最后循環結束了,肯定是其中有一個鏈表被遍歷完了,也就是l1或者l2傳遞到了這兩個鏈表的尾節點,沒法再next下去了。
跳出循環,此時來到了接下來的if l1 is not None:這個判斷條件,我們假設遍歷完以后,l1所在的鏈表1還有剩余的幾個節點,l2所在的鏈表2已經遍歷完了,那么pre.next = l1這個意思就是把pre引向l1之后的那幾個節點,也就是把新鏈表跟剩下
的鏈表連接起來
最后return的是new_list.next,因為new_list是根節點,new_list.next才是頭節點!
二、用遞歸的解法
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if not l1:
            return l2
        if not l2:
            return l1
        if l1.val <= l2.val:
            ret = l1
            ret.next = self.mergeTwoLists(l1.next, l2)
        else:
            ret = l2
            ret.next = self.mergeTwoLists(l1, l2.next)
        return ret

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM