[英]Python Logic of ListNode in Leetcode
Here is the definition of ListNote
class in LeetCode
:这里的定义
ListNote
类LeetCode
:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
For the code:对于代码:
result = ListNode(0)
#result = 0 -> None
result_tail = result
#result_tail = 0 -> None
result_tail.next = ListNode(1)
#result_tail = 0 -> 1 -> None
#result = 0 -> 1 -> None
result_tail = result_tail.next
#result_tail = 1 -> None
#result = 0 -> 1 -> None
result_tail.next = ListNode(2)
#result_tail = 1 -> 2 -> None
#result = 0 -> 1 -> 2 -> None
result_tail = result_tail.next
#result_tail = 2 -> None
#result = 0 -> 1 -> 2 -> None
The values in comments are from my guessing.评论中的值来自我的猜测。 I cannot understand the step
我无法理解这一步
result_tail = result_tail.next
result_tail = result
is pass by reference, so when result_tail
becomes 1 -> None
, result
should also become 1 -> None
. result_tail = result
是通过引用传递的,所以当result_tail
变成1 -> None
, result
也应该变成1 -> None
。 Why does result
still keep 0 -> 1 -> None
?为什么
result
仍然保持0 -> 1 -> None
? And when result_tail
becomes 1 -> 2 -> None
, why does result
extend its tail to 0 -> 1 -> 2 -> None
?当
result_tail
变为1 -> 2 -> None
,为什么result
将其尾部扩展到0 -> 1 -> 2 -> None
?
result_tail = result_tail.next
is something like就像
result_tail = result.next.next
Can anyone tell me the logic here?谁能告诉我这里的逻辑?
The short answer to this is that, Python is a pass-by-object-reference language, not pass-by-reference as implied in the question.对此的简短回答是,Python 是一种传递对象引用语言,而不是问题中暗示的传递引用。 It means that:
这意味着:
result
and result_tail
are two variables that happen to point at the same value result
和result_tail
是两个恰好指向同一个值的变量result_tail.next = ListNode(1)
) will affect the value shown by result
result_tail.next = ListNode(1)
)的变异/更改将影响result
显示的值result_tail
to another value will NOT affect the value of result
result_tail
分配/指向另一个值不会影响result
的值result_tail = result_tail.next
is assigning the next node of the node that is currently assigned by the variable result_tail = result_tail.next
是赋值当前变量赋值的节点的下一个节点The following is an visualization of the values that are assigned to the variables ( r
= result
, rt
= result_tail
):以下是分配给变量的值的可视化(
r
= result
, rt
= result_tail
):
result = ListNode(0)
#r
#0 -> None
result_tail = result
#r
#0 -> None
#rt
result_tail.next = ListNode(1)
#r
#0 -> 1 -> None
#rt
result_tail = result_tail.next
#r
#0 -> 1 -> None
# rt
result_tail.next = ListNode(2)
#r
#0 -> 1 -> 2 -> None
# rt
result_tail = result_tail.next
#r
#0 -> 1 -> 2 -> None
# rt
References for additional reading:补充阅读参考:
First, thank you so much for posting this question.首先,非常感谢您发布这个问题。 I worked on the same problem and saw this piece of code and was puzzled too.
我解决了同样的问题,看到了这段代码,也很困惑。 Then I followed some comments from leetcode and came here.
然后我跟着 leetcode 的一些评论来到了这里。
I realize that my problem was that I didn't have a pen and paper earlier.我意识到我的问题是我之前没有笔和纸。 After I drew the linked list on the paper by following the loop, it turned out to be quite clear.
我按照循环在纸上画了链表后,结果就很清楚了。
If you are still not clear about this, please try to draw the linked list by following the logic.如果您对此还不是很清楚,请尝试按照逻辑绘制链表。 Not sure if I got the right term here but below is my understanding.
不确定我是否在这里得到了正确的术语,但以下是我的理解。
To be honest, I do not think this is related to pass by reference or value.老实说,我不认为这与通过引用或值传递有关。 To me, this is just about two variables being assigned with the same value(memory location) at the beginning.
对我来说,这只是在开始时为两个变量分配了相同的值(内存位置)。 Think of variables as storage of address.
将变量视为地址的存储。 Address is the real memory location which is the start of some value.
地址是实际内存位置,它是某个值的开始。 Later on, one variable(result_tail) kept getting reassigned to a different location and one(result) stays the same.
后来,一个变量(result_tail)不断被重新分配到不同的位置,而 one(result)保持不变。
Result and result_tail both point to the location of 0|None before the while loop. Result 和 result_tail 都指向 while 循环前的 0|None 位置。
0|None
grew into 0->7|None
, then 0->7->0|None
and at last 0->7->0->8|None
by result_tail.next being assigned every time. 0|None
变成0->7|None
,然后是0->7->0|None
,最后是0->7->0->8|None
通过 result_tail.next 每次都被分配。 Result_tail gets reassigned so value changed during each loop, but result points to the same location which is the 0->....
Thus the result. Result_tail 被重新分配,因此在每个循环期间值都会改变,但结果指向相同的位置,即
0->....
因此结果。
For those reading this in the future: I wanted to debug linked list problems on a local environment so here is what I did.对于那些将来阅读本文的人:我想在本地环境中调试链表问题,所以这就是我所做的。
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def __repr__(self):
return "ListNode(val=" + str(self.val) + ", next={" + str(self.next) + "})"
def list_to_LL(arr):
if len(arr) < 1:
return None
if len(arr) == 1:
return ListNode(arr[0])
return ListNode(arr[0], next=list_to_LL(arr[1:]))
def reverseList(head: ListNode) -> ListNode:
prev = None
while head:
next_node = head.next
head.next = prev
prev = head
head = next_node
return prev
# test cases
t1 = list_to_LL([1, 2, 3, 4, 5]) #ListNode(val=1, next={ListNode(val=2, next={ListNode(val=3, next={ListNode(val=4, next={ListNode(val=5, next={None})})})})})
t2 = list_to_LL([1, 2]) #ListNode(val=1, next={ListNode(val=2, next={None})})
t3 = list_to_LL([])
# answers
print(reverseList(t1))
print(reverseList(t2))
print(reverseList(t3))
All above answers seems good.以上所有答案似乎都很好。 I am just adding up an example for the reader's understanding.
我只是举个例子供读者理解。
Input given : [[1,4,5],[1,3,4],[2,6]]
给定输入:
[[1,4,5],[1,3,4],[2,6]]
ListNode object description: ListNode 对象说明:
[ListNode{val: 1, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}}, ListNode{val: 1, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}, ListNode{val: 2, next: ListNode{val: 6, next: None}}]
Hope you got the CRUX!希望你得到了 CRUX!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.