给定一个数组,我希望在0=<i<n
的i处找到当前元素右侧的最小元素,并将相应最小元素的索引存储在另一个数组中。
例如,我有一个数组A = {1,3,6,7,8} 结果数组将包含R = {1,2,3,4}。(R数组存储指向min元素的索引)。 我只能想到O(N ^ 2)方法..对于A中的每个元素,我将遍历A的右边的剩余元素并找到最小值。 是否可以在O(N)中执行此操作?我想用解决方案来解决另一个问题。
答案 0 :(得分:1)
你应该能够在O(n)中通过从右手侧填充数组并保持当前最小值的索引来执行此操作,如下面的伪代码:
def genNewArray (oldArray):
newArray = new array[oldArray.size]
saveIndex = -1
for i = newArray.size - 1 down to 0:
newArray[i] = saveIndex
if saveIndex == -1 or oldArray[i] < oldArray[saveIndex]:
saveIndex = i
return newArray
这会通过数组一次,为您提供O(n)时间复杂度。它可以做到这一点,因为一旦你找到超出元素N的最小值,如果元素N小于当前最小值,它将仅对元素N-1改变。
以下Python代码显示了这一点:
def genNewArray (oldArray):
newArray = []
saveIndex = -1
for i in range (len (oldArray) - 1, -1, -1):
newArray.insert (0, saveIndex)
if saveIndex == -1 or oldArray[i] < oldArray[saveIndex]:
saveIndex = i
return newArray
oldList = [1,3,6,7,8,2,7,4]
x = genNewArray (oldList)
print "idx", [0,1,2,3,4,5,6,7]
print "old", oldList
print "new", x
这个输出是:
idx [0, 1, 2, 3, 4, 5, 6, 7]
old [1, 3, 6, 7, 8, 2, 7, 4]
new [5, 5, 5, 5, 5, 7, 7, -1]
你可以看到新数组(第二个)的每个元素的索引正确地指向原始数据(第一个)中每个元素右边的最小值。
请注意,我已经采用了“右边”的一个特定定义,这意味着它不包含当前元素。如果“右边”的定义包含当前元素,只需更改循环中insert
和if
语句的顺序,以便首先更新索引:
idx [0, 1, 2, 3, 4, 5, 6, 7]
old [1, 3, 6, 7, 8, 2, 7, 4]
new [0, 5, 5, 5, 5, 5, 7, 7]
由于您知道可以在最后一个元素找到最后一个元素的最小索引,因此代码将删除对saveIndex
的检查:
def genNewArray (oldArray):
newArray = []
saveIndex = len (oldArray) - 1
for i in range (len (oldArray) - 1, -1, -1):
if oldArray[i] < oldArray[saveIndex]:
saveIndex = i
newArray.insert (0, saveIndex)
return newArray
答案 1 :(得分:0)
看起来像HW。设f(i)表示i处元素右边的最小元素的索引。现在考虑向后走(填充f(n-1),然后f(n-2),f(n-3),...,f(3),f(2),f(1))并思考关于f(i)的信息如何为您提供f(i-1)的信息。