【问题标题】:merging two sorted linked lists into one linked list in python在python中将两个排序的链表合并为一个链表
【发布时间】:2014-04-25 18:38:33
【问题描述】:

这是我的代码:

def merge_lists(head1, head2):
    if head1 is None and head2 is None:
        return None
    if head1 is None:
        return head2
    if head2 is None:
        return head1
    if head1.value < head2.value:
        temp = head1
    else:
        temp = head2
    while head1 != None and head2 != None:
        if head1.value < head2.value:
            temp.next = head1
            head1 = head1.next
        else:
            temp.next = head2
            head2 = head2.next
    if head1 is None:
        temp.next = head2
    else:
        temp.next = head1
    return temp
    pass

这里的问题卡在无限循环中。谁能告诉我问题是什么

示例如下:

 assert [] == merge_lists([],[])
 assert [1,2,3] == merge_lists([1,2,3], [])
 assert [1,2,3] == merge_lists([], [1,2,3])
 assert [1,1,2,2,3,3,4,5] == merge_lists([1,2,3], [1,2,3,4,5])

【问题讨论】:

  • Python 原生列表成员没有 headvalue 属性。您的示例无法按原样运行。
  • 我没明白你的意思你能告诉我更清楚吗@mtrw
  • @srikarthikmodukuri 我们不知道“head1”和“head2”指的是什么——您没有将它们包含在代码示例中。请做。
  • @srikarthikmodukuri - 如果head1 = [1,2,3] 然后访问head1.value 将给出错误AttributeError: 'list' object has no attribute 'value'。因此,对于本机 python 列表,该程序将永远无法工作。您是否将一些不同类型的列表传递给函数merge_lists??
  • 这里 head1 表示一个排序列表,head2 表示另一个排序列表@selllikesybok

标签: python list linked-list sorted


【解决方案1】:

首先让我说清楚,这是我提到的leet代码的问题,所以这里我只是试图回答问题,逻辑本身。

时间复杂度:O(n+m),其中 n 是 len(l1),m 是 len(l2),因为我们只遍历一次。

空间复杂度:O(1),我们不创建任何新对象,只是相互重新连接。

 class ListNode:
     def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
 class Solution:
     def mergeTwoLists(self, l1, l2):
        head = res = ListNode()
    
        while l1 and l2:
            if l1.val <= l2.val:
                res.next = l1
                l1 = l1.next
            else:
                res.next = l2
                l2 = l2.next
            res = res.next
        if l1: res.next = l1
        if l2: res.next = l2
        return(head.next)

#创建一个新的链表,用于存储结果

#这里我使用了两个引用到同一个列表,因为我应该返回列表的根

过程中会用到#head,并返回res。 ——

【讨论】:

  • 欢迎来到 Stack Overflow!感谢您提供此算法及其时间和空间复杂度。你能解释一下它是如何工作的吗?为什么要有 Solution 类而不是 mergeTwoLists 函数? headres 有什么区别,为什么都指向同一个对象?
  • 其实让我说清楚,就是我提到的leet代码的问题,所以这里我只是试图回答问题,逻辑本身。
  • #创建一个新的链表,用于存储结果将被退回。
  • 希望你能明白。
  • 好的,我会这样做的。
【解决方案2】:

对我来说,将 LinkedList 转换为列表并返回更符合 Python 风格。 我还实现了打印功能来输出LinkedList,这有助于测试和调试。

def ln_to_list(ln):
    tmp = ln
    lst = [ln.val]
    while tmp.next:
        tmp = tmp.next
        lst.append(tmp.val)
    return lst

def print_ln(ln):
    return '->'.join([str(el) for el in ln_to_list(ln)])
    
def ln_from_list(lst):
    if not lst or len(lst) == 0: 
        return None
    head = ListNode(lst[0])
    tmp = head
    for i in lst[1:]:
        tmp.next = ListNode(i)
        tmp = tmp.next
    return head

【讨论】:

    【解决方案3】:

    完整代码:-

    为链表的每个节点定义“节点”类。

    class Node:
        def __init__(self,data):
            self.data = data
            self.next = None
    

    “链表”类的定义。

    class linkedlist:
        def __init__(self):
            self.head = None
    

    “合并”函数的定义。

    参数“ll1”和“ll2”是两个链表的头部。

    def merge_lists(ll1, ll2):
        if ll1 is None:
            return ll2
        if ll2 is None:
            return ll1
    
        if (ll1.data < ll2.data):
            ll1.next = merge_lists(ll1.next, ll2)
            return ll1
        else:
            ll2.next = merge_lists(ll2.next, ll1)
            return ll2
    

    将输入输入到列表中。

    l1 = []
    try:
        l1 = list(map(int,input().strip().split()))
    except EOFError:
        pass
    l2 = []
    try:
        l2 = list(map(int,input().strip().split()))
    except EOFError:
        pass
    

    根据输入列表值创建链表,即 ll1ll2

    ll1 = linkedlist()
    ll1.head = Node(l1[0])
    itr1 = ll1.head
    for i in range(1,n1):
        temp = Node(l1[i])
        itr1.next = temp
        itr1 = itr1.next
    
    ll2 = linkedlist()
    ll2.head = Node(l2[0])
    itr2 = ll2.head
    for i in range(1,n2):
        temp = Node(l2[i])
        itr2.next = temp
        itr2 = itr2.next
    

    通过传递两个链表的头部使用合并函数合并两个排序链表

    itr = merge(ll1.head,ll2.head)
    

    “合并”函数返回一个迭代器本身,其值打印为:

    while itr != None:
        print(itr.data,end=" ")
        itr = itr.next
    

    自定义输入输出:-

    输入

    1

    4

    1 3 5 7

    4

    2 4 6 12

    输出

    1 2 3 4 5 6 7 12

    【讨论】:

    • 您好,感谢您的反馈。但是,解释这如何解决 OP 问题以及为什么他的解决方案不起作用更有价值。
    • @WaLinke 感谢指出,我已经更新了合并两个链表的解决方案,并附有解释。
    【解决方案4】:

    合并两个排序链表的递归算法

    def merge_lists(h1, h2):
        if h1 is None:
            return h2
        if h2 is None:
            return h1
    
        if (h1.value < h2.value):
            h1.next = merge_lists(h1.next, h2)
            return h1
        else:
            h2.next = merge_lists(h2.next, h1)
            return h2
    

    【讨论】:

    • 你能指定这个解决方案的时间和空间复杂度吗?
    【解决方案5】:

    当前代码的问题是它会导致临时节点的下一个它从当前节点导航到下一个节点的副作用。当当前临时节点当前节点时,这是有问题的。

    也就是说,想象一下这种情况:

    temp = N
    temp.next = N  # which means N.next = N
    N = N.next     # but from above N = (N.next = N) -> N = N
    

    有一个更正的版本,还有一些其他更新:

    def merge_lists(head1, head2):
        if head1 is None:
            return head2
        if head2 is None:
            return head1
    
        # create dummy node to avoid additional checks in loop
        s = t = node() 
        while not (head1 is None or head2 is None):
            if head1.value < head2.value:
                # remember current low-node
                c = head1
                # follow ->next
                head1 = head1.next
            else:
                # remember current low-node
                c = head2
                # follow ->next
                head2 = head2.next
    
            # only mutate the node AFTER we have followed ->next
            t.next = c          
            # and make sure we also advance the temp
            t = t.next
    
        t.next = head1 or head2
    
        # return tail of dummy node
        return s.next
    

    【讨论】:

    • 感谢您告诉我,我很好地理解了概念和代码。谢谢
    • 你能解释一下虚拟节点的概念吗?我确实有更多的线路和控制流。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 2014-09-18
    • 2011-01-21
    相关资源
    最近更新 更多