在python中更改分配顺序时“超出时间限制” 现在我也明白了这个问题! ˆ_ˆ递归迭代

问题描述

我正在处理链表中k个节点的问题反转组。当我编写分配操作以进行冲销时,我给出了:

cur,cur.next,prev = cur.next,prev,cur

其中curprev表示当前节点和先前节点。发生的最有趣的事情是,当我给:

cur.next,cur,prev = prev,cur

这是可以接受的,而前者却给了我超过时间的限制。

我相信在Python中,将多个变量分配为元组,并且仅考虑所有变量的先前值。那么两个陈述应该是完全相同的权利吗?还是我错了?请在这里帮助我。

这是一个leetcode问题,我提供了整个代码以防万一。该行标有3 *,如果我单独更改该行,代码将从接受的跃跃到超过时间限制。

 h=jump=ListNode(0)
 h.next=left=right=head
 while True:
            i=0
            while i<k and right:
                i+=1
                right=right.next
            if i==k:
                prev=right
                cur=left
                for _ in range(k):
                    ***cur.next,cur***
                jump.next,jump,left=prev,left,right
            else:
                return h.next

上面的代码被接受。仅当我更改线路时,它才陷入一个循环,超过了时间限制。

解决方法

分配是from left to right,所以...

cur,cur.next,... = ...

以上内容首先分配给cur。然后转到cur.next,其中cur已经是新值

cur.next,cur,... = ...

这首先分配给cur.next,其中cur 仍然是旧值。然后转到cur

所以您与众不同。您更改了不同节点的.next

,

很好的问题!

现在我也明白了这个问题! (ˆ_ˆ)

这是链接列表中非常普遍的问题,在遍历链接列表或执行任何其他操作时,我们应始终注意语句更改的顺序。

事实是,如果我们的陈述中的某些必需命令丢失了(在这种情况下),最终将发生以下两种情况之一:

  • 如果您愿意的话,任何一个节点都将丢失与下一个节点的链接,并且该节点将变为无链接;
  • 或者一个节点将链接回其自身(如圆形),并且列表将变得过时;

您的代码正确无误即可正常工作,而没有超过时间限制(经过测试):

# 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 reverseKGroup(self,head,k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        h = jump = ListNode(0)
        h.next = left = right = head
        while True:
            i = 0
            while i < k and right:
                i += 1
                right = right.next
            if i == k:
                prev = right
                cur = left
                for _ in range(k):
                    cur.next,prev = prev,cur
                jump.next,jump,left = prev,left,right
            else:
                return h.next

我们还可以使用辅助功能。会在没有超过时间限制(TLE)的情况下通过:

class Solution:
    def reverseKGroup(self,k):
        def rev(head,count):
            prev,curr,next = None,head
            while count > 0:
                next = curr.next
                curr.next = prev
                prev,count = curr,next,count - 1
            return (curr,prev)
        count,curr = 0,head
        while curr and count < k:
            curr,count = curr.next,count + 1
        if count < k:
            return head
        new_head,prev = rev(head,count)
        head.next = self.reverseKGroup(new_head,k)
        return prev

这里是LeetCode的官方解决方案,带有解释性注释:

递归

class Solution:
    
    def reverseLinkedList(self,k):
        
        # Reverse k nodes of the given linked list.
        # This function assumes that the list contains 
        # atleast k nodes.
        new_head,ptr = None,head
        while k:
            
            # Keep track of the next node to process in the
            # original list
            next_node = ptr.next
            
            # Insert the node pointed to by "ptr"
            # at the beginning of the reversed list
            ptr.next = new_head
            new_head = ptr
            
            # Move on to the next node
            ptr = next_node
            
            # Decrement the count of nodes to be reversed by 1
            k -= 1
        
        # Return the head of the reversed list
        return new_head
                
    
    def reverseKGroup(self,head: ListNode,k: int) -> ListNode:
        
        count = 0
        ptr = head
        
        # First,see if there are atleast k nodes
        # left in the linked list.
        while count < k and ptr:
            ptr = ptr.next
            count += 1
        
        # If we have k nodes,then we reverse them
        if count == k: 
            
            # Reverse the first k nodes of the list and
            # get the reversed list's head.
            reversedHead = self.reverseLinkedList(head,k)
            
            # Now recurse on the remaining linked list. Since
            # our recursion returns the head of the overall processed
            # list,we use that and the "original" head of the "k" nodes
            # to re-wire the connections.
            head.next = self.reverseKGroup(ptr,k)
            return reversedHead
        return head

迭代

class Solution:
    
    def reverseLinkedList(self,k: int) -> ListNode:
        
        ptr = head
        ktail = None
        
        # Head of the final,moified linked list
        new_head = None
        
        # Keep going until there are nodes in the list
        while ptr:
            count = 0
            
            # Start counting nodes from the head
            ptr = head
            
            # Find the head of the next k nodes
            while count < k and ptr:
                ptr = ptr.next
                count += 1

            # If we counted k nodes,reverse them        
            if count == k:
                
                # Reverse k nodes and get the new head
                revHead = self.reverseLinkedList(head,k)
                
                # new_head is the head of the final linked list
                if not new_head:
                    new_head = revHead
                
                # ktail is the tail of the previous block of 
                # reversed k nodes
                if ktail:
                    ktail.next = revHead
                    
                ktail = head 
                head = ptr
        
        # attach the final,possibly un-reversed portion
        if ktail:
            ktail.next = head
        
        return new_head if new_head else head

参考文献

  • 有关其他详细信息,请参见Discussion Board,在这里您可以找到许多具有各种languages且已被广泛接受的解决方案,包括低复杂度算法和渐近runtime / {{ 3}}分析memory1