我有以下问题(来自 AlgoExpert):
<块引用>给定一个整数数组和一个整数。编写一个函数,将数组中该整数的所有实例移动到数组末尾并返回数组。 该函数应该就地执行此操作,并且不需要维护其他整数的顺序。
例如:
array = [2,1,2,2,2,3,4,2]
toMove = 2
Expected = [1,3,4,2,2,2,2,2]
(the numbers 1,3,4 could be ordered differently)
def moveElementToEnd(array, toMove):
l = 0
r = len(array) - 1
while l < r:
if array[l] == toMove and array[r] == toMove:
r -= 1
elif array[l] != toMove and array[r] != toMove:
l += 1
elif array[l] == toMove and array[r] != toMove:
array[l], array[r] = array[r], array[l]
l += 1
r -= 1
return array
这会超时,但是当我按如下方式更改 if 语句时,它工作正常:
def moveElementToEnd(array, toMove):
if len(array) < 1:
return array
l = 0
r = len(array) - 1
while l < r:
if array[l] == toMove and array[r] != toMove:
array[l], array[r] = array[r], array[l]
l += 1
r -= 1
elif array[l] != toMove and array[r] != toMove:
l += 1
else:
r -= 1
return array
是什么导致了第一个代码片段中的超时?
答案 0 :(得分:2)
您可以将 sort
与自定义 key
一起使用,将每个元素与 toMove
进行比较。所有 False
值都在左边,所有 True
值都在右边。因此,所有 toMove
值都将位于列表的后面。
>>> array = [2,1,2,2,2,3,4,2]
>>> toMove = 2
>>> array.sort(key=lambda i: i == toMove)
>>> array
[1, 3, 4, 2, 2, 2, 2, 2]
答案 1 :(得分:1)
您的第一个代码块可能会产生无限循环,因为在某些情况下,循环不会更改任何一个索引。这是因为您的 if ..elif..
构造最后没有包罗万象(使用 else
)
所以是这部分有问题:
if array[l] == toMove and array[r] == toMove:
r -= 1
elif array[l] != toMove and array[r] != toMove:
l += 1
elif array[l] == toMove and array[r] != toMove:
array[l], array[r] = array[r], array[l]
l += 1
r -= 1
当 array[l] != toMove
和 array[r] == toMove
时它不做任何事情,因此循环将无限运行。
您可以将四种可能性描述如下:
array[r] == toMove |
array[r] != toMove |
|
---|---|---|
array[l] == toMove |
1 | 2 |
array[l] != toMove |
3 | 4 |
您的错误代码处理情况 1、4 和 2(按此顺序),但不处理情况 3
工作代码首先处理情况 2 和 4,在最后的 else
中,它一起处理情况 1 和 3。
您希望在这四种情况下发生的是:
array[r] == toMove |
array[r] != toMove |
|
---|---|---|
array[l] == toMove |
r-=1 |
交换,l+=1; r-=1 |
array[l] != toMove |
r-=1 |
l+=1 |
因此,您的代码的修复是改变这一点:
if array[l] == toMove and array[r] == toMove:
为此:
if array[r] == toMove:
所以它一次处理两种情况。
有了这个变化,第二个条件可以简化:如果执行到了那里,我们知道array[r] != toMove
,所以不需要测试。也不再需要第二个 elif
条件,因为只要执行到达该条件,该条件就会为真。您可以将其更改为 else
。
if array[r] == toMove:
r -= 1
elif array[l] != toMove:
l += 1
else:
array[l], array[r] = array[r], array[l]
l += 1
r -= 1
而且这个版本比你展示的工作版本更简洁。