问题描述
只需一步,我们就可以使它等于第二个最大元素,并且必须使所有元素等于最小元素。 下面给出了我的代码,它工作正常,但我想降低它的时间复杂度。
def No_Books(arr,n):
arr = sorted(arr)
steps = 0
while arr[0]!= arr[arr.index(max(arr))]:
max1 = max(arr)
count = arr.count(max1)
scnd_max = arr.index(max1)-1
arr[scnd_max+count] = arr[scnd_max]
steps += 1
return steps
n = int(input())
arr = [int(x) for x in input().split()]
print(No_Books(arr,n))
5
4 5 5 2 4
6
这里需要的最小移动是 6
解决方法
我是这样解释这个问题的:
对于数组中的每个元素,您只能执行一项操作,该操作是将索引的值替换为数组的当前第二大元素。
需要多少次操作才能使整个数组的值等于初始最小值?
使用示例输入 4 5 5 2 4
需要经过以下步骤:
Array - step - comments
4 5 5 2 4 - 0 - start
4 4 5 2 4 - 1 - replace the first 5 with 4 (the second-largest value in the array)
4 4 4 2 4 - 2 - replace the second 5 with 4
2 4 4 2 4 - 3 - replace the first 4 with 2
2 2 4 2 4 - 4
2 2 2 2 4 - 5
2 2 2 2 2 - 6
It took 6 steps,so the result is 6.
如果这是正确的,那么我可以将您的二次解(O(n^2),其中 n 是数组的大小)更改为拟线性解(O(n + mlogm),其中 n 是数组的大小)数组,m 是数组中唯一值的个数),如下所示。
该方法是注意对于每个小于自身的唯一值,每个值都需要下降到下一个最大值。因此,如果我们能够跟踪每个唯一值的计数,我们就可以确定步数,而无需实际进行任何数组更新。
在伪代码中:
function determineSteps(array):
define map from integer to integer,defaulting to 0
for each value in array: // Linear in N
map(value)++
sort map by key,descending // M log M
// largerCount is the number of elements larger than the current second-largest value
define largerCount,assign 0 to largerCount
// stepCount is the number of steps required
define stepCount,assign 0 to stepCount
for each key in map except the last: // Linear in M
largerCount = largerCount + map(key)
stepCount = stepCount + largerCount
return stepCount
在您的示例输入中:
4 5 5 2 4
Create map { 4: 2,5: 2,2: 1 }
Sort map by key,descending: { 5: 2,4: 2,2: 1 }
stepCount = 0
largerCount = 0
Examine key = 5,map(key) = 2
largerCount = 0 + 2 = 2
stepCount = 0 + 2 = 2
Examine key = 4,map(key) = 2
largerCount = 2 + 2 = 4
stepCount = 2 + 4 = 6
return 6