最近我阅读了破解代码,在第2章中介绍了解决多数链表问题的runner方法。
给定一个链表a1 a2 ... a b1 b2 ... bn重新排列为a1 b1 a2 b2 ... a bn。
它说我们应该使用两个跑步者,速度更快的跑步者应该跑得慢一倍。
因为它总数是偶数,所以当结束时跑得更快时,链接列表中间的速度就越慢。然后将较快的跑步者放在链接列表的开头,并插入较慢的跑步者之后较慢的指向的元素。
我知道这个原则,但我的问题是:
例如
1 2 3 4 1 2 3 4
首先,两位选手都指向“1”,
然后较快的跑步者指向“3”,较慢的指向“2”。
越快的乐趣者指向第二个“1”,越慢指向“3”。
较快的跑步者指向第二个“3”,较慢的指向“4”。
然后呢?我该怎么办?我不能把速度更快的跑者放到第一个“1”,因为我还没有到达链表的末尾。与较慢的一样,它没有到达链表的中间。
如果我在链接列表中添加头部,则较快的跑步者和较慢的跑步者可以到达中间和结束。我的意思是它看起来如下:
0 1 2 3 4 1 2 3 4;
所以我想知道,如果我想使用runner方法来解决这个问题,我应该为快跑者和慢跑者添加一个索引吗?
答案 0 :(得分:1)
# This is a testing function by Pengyu CHEN (cpy.prefers.you[at]gmail.com)
# For answering questions on StackOverflow.com
# COPYLEFT, ALL WRONGS RESERVED.
"""
To rearrange a lst from a_1->a_2->...->a_n->b_1->b_2->...->b_n
to a_1->b_1->...->a_i->b_i->...->a_n->b_n
"""
def linked_list_rearrange(lst):
# step 1:
fast = lst.head
slow = lst.head
while fast != None:
fast = fast.next
fast = fast.next # assuming here it won't generage any errors
slow = slow.next
# step 2:
fast = lst.head
# now slow is at middle of the list, means b_1
while slow != None:
temp = slow.next
slow.next = fast.next
fast.next = slow
fast = slow.next
slow = temp
return lst
假设您是一名翻译并将输入列表提供给上述功能。通过遵循其步骤,您可以清楚地了解我认为的算法。
更新:修正:从fase到fast的拼写错误 更新:已添加:copyright(copyleft)信息。
答案 1 :(得分:0)
以编程方式思考。当它表示速度提高两倍时,它意味着在一次迭代中,它需要一步,然后由另一步完成。
所以在the faster runner points to the second "3", the slower points to the "4".
之后,较慢的移动到第二个“1”,而较快的第一个移动到第二个“4”。如果节点(更快指向的节点)指向NULL
(或者如果它是列表中的最后一个节点),则需要更快地检查移动,更快地移动到列表中的第一个节点。
然后,只需将当前较慢的节点(第二个“1”)移动到当前指向较快的节点(第一个“1”)之后。
HTH