我被要求反转一个以head为参数的参数,其中as head是一个链表,例如:1-
def reverse_linked_list(head):
temp = head
head = None
temp1 = temp.next
temp2 = temp1.next
temp1.next = None
temp2.next = temp1
temp1.next = temp
return temp2
class Node(object):
def __init__(self,value=None):
self.value = value
self.next = None
def to_linked_list(plist):
head = None
prev = None
for element in plist:
node = Node(element)
if not head:
head = node
else:
prev.next = node
prev = node
return head
def from_linked_list(head):
result = []
counter = 0
while head and counter < 100: # tests don't use more than 100 nodes, so bail if you loop 100 times.
result.append(head.value)
head = head.next
counter += 1
return result
def check_reversal(input):
head = to_linked_list(input)
result = reverse_linked_list(head)
assert list(reversed(input)) == from_linked_list(result)
它是这样调用的:check\u reversion([1,2,3])
。我编写的用于反转列表的函数给出了[3,2,1,2,1,2,2,1]
,并且只适用于长度为3的列表。如何将其概括为长度n
的列表?
下面是一种“就地”反转列表的方法。它以恒定时间O(n)运行,并且使用零额外空间。
def reverse(head):
if not head:
return head
h = head
q = None
p = h.next
while (p):
h.next = q
q = h
h = p
p = h.next
h.next = q
return h
这里有一个动画来显示算法正在运行。
(#为动画目的象征空/无)
我发现blckknght的答案很有用,而且肯定是正确的,但我很难理解到底发生了什么,这主要是因为Python的语法允许在一行上交换两个变量。我还发现变量名有点混乱。
在这个例子中,我使用以前的,当前的,tmp
。
def reverse(head):
current = head
previous = None
while current:
tmp = current.next
current.next = previous # None, first time round.
previous = current # Used in the next iteration.
current = tmp # Move to next node.
head = previous
以具有3个节点的单链表(head=n1
,tail=n3
)为例。
n1-
在第一次进入
while
循环之前,previous
被初始化为None
,因为头部之前没有节点(n1
)。
我发现想象变量
previous、current、tmp
沿着链接列表“移动”是很有用的,总是按照这个顺序。
第一次迭代
previous=None
[n1]-
第二次迭代
[n1]-
第三次迭代
# next is None
[n1]-
因为
而
循环退出时当前==无
列表的新头部必须设置为前一个
,这是我们访问的最后一个节点。
编辑
在Python中添加完整的工作示例(带有注释和有用的
str
表示)。我使用的是tmp
而不是next
,因为next
是一个关键字。然而,我碰巧认为这是一个更好的名字,使算法更清晰。
class Node:
def __init__(self, value):
self.value = value
self.next = None
def __str__(self):
return str(self.value)
def set_next(self, value):
self.next = Node(value)
return self.next
class LinkedList:
def __init__(self, head=None):
self.head = head
def __str__(self):
values = []
current = self.head
while current:
values.append(str(current))
current = current.next
return ' -> '.join(values)
def reverse(self):
previous = None
current = self.head
while current.next:
# Remember `next`, we'll need it later.
tmp = current.next
# Reverse the direction of two items.
current.next = previous
# Move along the list.
previous = current
current = tmp
# The loop exited ahead of the last item because it has no
# `next` node. Fix that here.
current.next = previous
# Don't forget to update the `LinkedList`.
self.head = current
if __name__ == "__main__":
head = Node('a')
head.set_next('b').set_next('c').set_next('d').set_next('e')
ll = LinkedList(head)
print(ll)
ll.revevse()
print(ll)
后果
a -> b -> c -> d -> e
e -> d -> c -> b -> a
被接受的答案对我来说毫无意义,因为它指的是一堆似乎不存在的东西(number
,node
,len
作为一个数字而不是一个函数)。因为这个作业可能已经很久了,我将发布我认为最有效的代码。
这用于执行破坏性反转,其中修改现有列表节点:
def reverse_list(head):
new_head = None
while head:
head.next, head, new_head = new_head, head.next, head # look Ma, no temp vars!
return new_head
函数的一个不太奇特的实现将使用一个临时变量和几个赋值语句,这可能更容易理解:
def reverse_list(head):
new_head = None # this is where we build the reversed list (reusing the existing nodes)
while head:
temp = head # temp is a reference to a node we're moving from one list to the other
head = temp.next # the first two assignments pop the node off the front of the list
temp.next = new_head # the next two make it the new head of the reversed list
new_head = temp
return new_head
另一种设计是在不改变旧列表的情况下创建一个全新的列表。如果要将列表节点视为不可变对象,则更合适:
class Node(object):
def __init__(self, value, next=None): # if we're considering Nodes to be immutable
self.value = value # we need to set all their attributes up
self.next = next # front, since we can't change them later
def reverse_list_nondestructive(head):
new_head = None
while head:
new_head = Node(head.value, new_head)
head = head.next
return new_head
问题内容: 我被要求反转一个以head为参数的参数,其中head是一个链表,例如:1-> 2-> 3这是从已经定义的函数返回的,我试图以这种方式实现函数reverse_linked_list: 称为:。我编写的用于反转列表的函数具有给定的功能,并且仅适用于长度为3的列表。如何将其概括为长度为列表的? 问题答案: U可以使用mod函数获取每次迭代的余数,并且显然可以帮助反转列表。我想你是R和D团的学
NowCoder 解题思路 递归 // java public ListNode ReverseList(ListNode head) { if (head == null || head.next == null) return head; ListNode next = head.next; head.next = null; ListNode
问题内容: Python的str对象没有内置的反向函数。实现这种方法的最佳方法是什么? 如果提供一个非常简洁的答案,请详细说明其效率。例如,str对象是否转换为其他对象等。 问题答案: 怎么样: 这是扩展切片语法。它的工作方式是通过保留和并指定步骤来反转字符串。
问题内容: 必须是O(n)并且是就地(空间复杂度为1)。下面的代码可以工作,但是有没有更简单或更完善的方法? 问题答案: 编辑以删除每次迭代的额外比较:
问题内容: 如何在Python中执行以下操作? 我需要一个数组的元素,但是要从头到尾。 问题答案: 你可以通过以下方式使用该函数: 请注意,它不会返回列表。你可以使用来获得反向列表。
一、题目 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。 二、解题思路 ①遍历。将指向下一个节点的指针指向上一个节点。 ②递归。先让指向下一个节点的指针为空,然后递归调用,最后再将指向下一个节点的指针指向上一个节点。 三、解题代码 遍历 /** * 反转单链表 * @param head * @return */ p