【问题标题】:merge 2 linked lists in sorted order按排序顺序合并 2 个链表
【发布时间】:2021-12-23 14:56:27
【问题描述】:

合并两个排序的链表并将其作为排序列表返回。列表应该由前两个列表的节点拼接而成。

我们有 l1:

ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 4, next: None}}}

和l2:

ListNode{val: 1, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}

我使用以下代码合并它们:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        print(l1)
        print(l2)
        out = ListNode(-1)
        temp = out
        while l1 and l2:
            if (l1.val < l2.val):
                temp.next = l1
                l1 = l1.next
            else:
                temp.next = l2
                l2 = l2.next
            temp = temp.next
        print(out)

这就是结果:

ListNode{val: -1, next: ListNode{val: 1, next: ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}}}}

我的问题是out 是如何更新的?

【问题讨论】:

    标签: python sorting merge linked-list


    【解决方案1】:

    如果有帮助,您甚至不需要任何临时节点。您可以重新链接现有节点,这会更简单:

    class Solution:
        def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
            if not (l1 and l2):
                return l1 or l2
            if l2.val < l1.val:
                l1, l2 = l2, l1
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
    

    【讨论】:

      【解决方案2】:

      outwhile 循环的第一次迭代中发生突变。

      这可能有助于将其可视化。

      就在循环开始之前,我们创建了一个虚拟节点(值为-1)并使用outtemp 引用它:

                         l1
                         ↓
                       ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 2    │    │ data: 4    │
                       │ next: ────────> │ next: ────────> │ next: None │
       out             └────────────┘    └────────────┘    └────────────┘
        ↓
      ┌────────────┐
      │ data: -1   │
      │ next: None │
      └────────────┘
        ↑
       temp            ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 3    │    │ data: 4    │
                       │ next: ────────> │ next: ────────> │ next: None │
                       └────────────┘    └────────────┘    └────────────┘
                         ↑
                         l2
      

      在第一次迭代中,我们进入else 块,其中temp变异。由于tempout 引用同一个对象,因此out 会发生变异。

                         l1
                         ↓
                       ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 2    │    │ data: 4    │
                       │ next: ────────> │ next: ────────> │ next: None │
       out             └────────────┘    └────────────┘    └────────────┘
        ↓
      ┌────────────┐
      │ data: -1   │
      │ next: ──────┐
      └────────────┘│
        ↑           │
       temp         │  ┌────────────┐    ┌────────────┐    ┌────────────┐
                    │  │ data: 1    │    │ data: 3    │    │ data: 4    │
                    └> │ next: ────────> │ next: ────────> │ next: None │
                       └────────────┘    └────────────┘    └────────────┘
                         ↑
                         l2
      

      此次更新后,l2temp 都被“移动”为指代它们的继任者。这结束了第一次迭代:

                         l1
                         ↓
                       ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 2    │    │ data: 4    │
                       │ next: ────────> │ next: ────────> │ next: None │
       out             └────────────┘    └────────────┘    └────────────┘
        ↓
      ┌────────────┐
      │ data: -1   │
      │ next: ──────┐
      └────────────┘│
                    │
                    │  ┌────────────┐    ┌────────────┐    ┌────────────┐
                    │  │ data: 1    │    │ data: 3    │    │ data: 4    │
                    └> │ next: ────────> │ next: ────────> │ next: None │
                       └────────────┘    └────────────┘    └────────────┘
                         ↑                 ↑
                        temp               l2
      

      我们实际上不必继续执行算法,因为从现在开始out 将不会再次变异:这项工作已经完成。但是让我们继续进行一次迭代(第二次迭代)。我们进入if 块,temp 再次发生变异(但这一次,它不是out 的同义词):

                         l1
                         ↓
                       ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 2    │    │ data: 4    │
                    ┌> │ next: ────────> │ next: ────────> │ next: None │
       out          │  └────────────┘    └────────────┘    └────────────┘
        ↓           └────────────────┐
      ┌────────────┐                 │
      │ data: -1   │                 │
      │ next: ──────┐                │
      └────────────┘│                │
                    │                │
                    │  ┌────────────┐│   ┌────────────┐    ┌────────────┐
                    │  │ data: 1    ││   │ data: 3    │    │ data: 4    │
                    └> │ next: ──────┘   │ next: ────────> │ next: None │
                       └────────────┘    └────────────┘    └────────────┘
                         ↑                 ↑
                        temp               l2
      

      ...l1temp 都转移到他们的继任者:

                        temp               l1
                         ↓                 ↓
                       ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 2    │    │ data: 4    │
                    ┌> │ next: ────────> │ next: ────────> │ next: None │
       out          │  └────────────┘    └────────────┘    └────────────┘
        ↓           └────────────────┐
      ┌────────────┐                 │
      │ data: -1   │                 │
      │ next: ──────┐                │
      └────────────┘│                │
                    │                │
                    │  ┌────────────┐│   ┌────────────┐    ┌────────────┐
                    │  │ data: 1    ││   │ data: 3    │    │ data: 4    │
                    └> │ next: ──────┘   │ next: ────────> │ next: None │
                       └────────────┘    └────────────┘    └────────────┘
                                           ↑
                                           l2
      

      这样继续下去,temp 将保持在连接的结果列表的尾部。在最后一次迭代之后,我们将得到这个:

                                                             l1
                                                             ↓
                       ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 2    │    │ data: 4    │
                    ┌> │ next: ────────> │ next: ──────┐   │ next: None │
       out          │  └────────────┘    └────────────┘│   └────────────┘
        ↓           └────────────────┐ ┌───────────────┘
      ┌────────────┐                 │ │                                
      │ data: -1   │                 │ │                                
      │ next: ──────┐                │ │                                
      └────────────┘│                │ │                                
                    │                │ │                                
                    │  ┌────────────┐│ │ ┌────────────┐    ┌────────────┐
                    │  │ data: 1    ││ │ │ data: 3    │    │ data: 4    │
                    └> │ next: ──────┘ └>│ next: ────────> │ next: None │
                       └────────────┘    └────────────┘    └────────────┘
                                                             ↑                
                                                            temp
      

      这项工作还没有完全完成,因为您发布的 sn-p 中缺少一些代码。当while 循环退出时,l1l2 之一将不是None,这表示仍需要附加到结果列表的部分。由于temp 指的是结果列表的当前尾部,我们应该将其next 引用设置为l1l2——以不是None 为准。

      所以代码在循环之后应该有如下语句:

      temp.next = l1 or l2
      

      ...导致:

                                                             l1
                                                             ↓
                       ┌────────────┐    ┌────────────┐    ┌────────────┐
                       │ data: 1    │    │ data: 2    │    │ data: 4    │
                    ┌> │ next: ────────> │ next: ──────┐ ┌>│ next: None │
       out          │  └────────────┘    └────────────┘│ │ └────────────┘
        ↓           └────────────────┐ ┌───────────────┘ └───────────────┐
      ┌────────────┐                 │ │                                 │
      │ data: -1   │                 │ │                                 │
      │ next: ──────┐                │ │                                 │
      └────────────┘│                │ │                                 │
                    │                │ │                                 │
                    │  ┌────────────┐│ │ ┌────────────┐    ┌────────────┐│
                    │  │ data: 1    ││ │ │ data: 3    │    │ data: 4    ││
                    └> │ next: ──────┘ └>│ next: ────────> │ next: ──────┘
                       └────────────┘    └────────────┘    └────────────┘
                                                             ↑                
                                                            temp
      

      最后,函数应该返回结果。由于out 指的是一个虚拟节点,我们不应该只返回out,而应该返回out.next

      return out.next
      

      返回的列表引用将是这个:

                 ┌────────────┐    ┌────────────┐    ┌────────────┐
                 │ data: 1    │    │ data: 2    │    │ data: 4    │
              ┌> │ next: ────────> │ next: ──────┐ ┌>│ next: None │
              │  └────────────┘    └────────────┘│ │ └────────────┘
              └────────────────┐ ┌───────────────┘ └───────────────┐
                               │ │                                 │
                 ┌────────────┐│ │ ┌────────────┐    ┌────────────┐│
                 │ data: 1    ││ │ │ data: 3    │    │ data: 4    ││
      returned → │ next: ──────┘ └>│ next: ────────> │ next: ──────┘
                 └────────────┘    └────────────┘    └────────────┘
      

      我希望这可以澄清它。

      【讨论】:

      • 是的,非常感谢
      猜你喜欢
      • 2020-12-15
      • 1970-01-01
      • 2019-06-12
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 2020-04-03
      • 2021-05-16
      • 2021-08-10
      相关资源
      最近更新 更多