为什么我的链接列表中有一个循环,尽管它事先被编码为退出



我正在编写代码来解决以下链表问题:https://leetcode.com/problems/swap-nodes-in-pairs/

总之,就是交换链表中的相邻节点。

class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if not head or not head.next: 
return []

prev= head
nex=head
connector= None
output = head.next
count = 0 
while prev:
curr = nex.next
if count>=1: 
connector.next = curr  
nex = curr.next
curr.next = prev
connector = prev
prev=nex
count +=1

return output

如果我运行input [1,2,3,4],我会得到一个Error - Found cycle in the ListNode。然而,当我用这个输入在纸上运行上面的代码时,它就像一个魅力!并在应该的时候退出——没有循环。你知道这种所谓的循环发生在哪里吗?

对于这个问题,您要保持的状态远远超过您需要的状态。例如,count是完全不必要的。您所需要的不是检查count >= 1,而是connector is not None。从一次迭代到下一次迭代,您真正需要的唯一状态是要交换的下一个节点,以及可能的后续节点(作为一种优化,以避免必须多次获取它(。

关于创建循环的特定bug,请考虑循环的第一次迭代。在循环的顶部,nex等于head,因此nex引用列表中的第一个节点。

然后它设置curr = next.next,因此curr引用列表中的第二个节点(如果没有第二个结点,则为None(。然后它设置nex = curr.next,因此nex现在引用列表中的第三个节点(如果没有第三个结点,则引用None(。但是这里有个bug。如果currNone呢?那么curr.next会导致一个错误,对吧?所以这个问题需要解决。

但假设列表至少有两个节点,此时我们有curr引用第二个节点,nex引用第三个节点(如果有(。该列表本身尚未更改。

现在设置curr.next = prev。由于curr是第二节点,而prev仍然是第一节点,因此它将第二节点的后继节点设置为第一节点。它现在创建了一个循环:第一个节点的继任者现在是第二个节点,第二个结点的继任者现在就是第一个节点。第三个节点(如果有的话(不再被列表引用。换句话说,它没有交换前两个节点。它只是在它们之间创造了一个循环。

在这一点上,它几乎偏离了轨道。提示:交换两个节点需要更改三个next属性:需要将最初引用对中第一个节点的属性更改为引用第二个,需要将对中第一节点的next属性更改为第二个的next属性,并且需要改变第二节点的CCD_ 26属性以引用第一节点。之后,第一个节点现在将是第二个节点,第二个点将是第一个节点:

... A -> first -> second -> B ...

变为:

... A -> second -> first -> B ...

所以A.next需要改变,first.next需要改变,而second.next需要改变。B无需更改。

我建议仔细研究逻辑,看看当有0、1、2、3…时会发生什么。。。列表中的节点。您会立即发现问题,这些问题已经确定,可以解决。

更新:以下是完整的解决方案(仅更改了Solution(:

class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
prev = None
curr = head
while curr and curr.next:
next = curr.next
if prev is None:
head = next
else:
prev.next = next
curr.next = next.next
next.next = curr
prev = curr
curr = curr.next
return head

请注意,循环中的每次迭代都会遍历两个列表节点。循环结束时的两个更新(设置prevcurr(使用更新后的curr节点,该节点现在是当前对中的第二个节点。

相关内容

  • 没有找到相关文章

最新更新