我正在尝试学习Python,并正在使用LeetCode进行练习。Problem 1721要求我们写一个函数,当传入链表时,该函数将成对交换相邻节点。例如:
Input : [A, B, C, D, E, F, G]
Output: [B, A, D, C, F, E, G]
我自己能想出一个解决方案,但我不明白下面的另一个解决方案。当作者写pre = self
时,pre
到底绑定到什么?我对关键字self
的理解使我相信它指的是Solution
类的示例,但我不知道这将如何帮助解决问题。我们不应该只处理链表吗?
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
pre, pre.next = self, head
while pre.next and pre.next.next:
a = pre.next
b = a.next
pre.next, b.next, a.next = b, a, b.next
pre = a
return self.next
我读过其他几个问题和其他介绍self
的网站,但它们都只提供了非常基本的构造函数和其他琐碎函数的示例。我不明白self.next
在这里是什么意思。
这是我在这个论坛上的第一个问题,所以如果有任何方法可以改进这个问题,请让我知道。先谢谢你。
1条答案
按热度按时间ru9i0ody1#
这个解决方案以一种相当“创造性”的方式使用了
self
。这里的self
是Solution
的示例--由LeetCode框架在执行类似下面的代码时创建:以这种方式使用
self
看起来很奇怪,因为self
不是ListNode
示例,也没有next
属性。下面的语句实际上是在self
上创建了一个next
属性:因此,循环将很高兴地访问这个
next
属性,而不必知道它实际上不属于ListNode
示例。循环结束后,可以检索next
属性以返回最终列表。这段代码的作者认为(ab)使用
self
作为虚拟节点。更常见的做法是创建这样一个虚拟节点,如下所示:作者没有创建这个节点,而是重用LeetCode的解决方案示例,从而节省了一点内存(和一行代码)。
我不建议做这样的事情,因为:
Solution
的 instance 上留下了对列表的引用。这是调用方可能没有意识到的副作用,可能会阻止某些垃圾收集的发生。