给定整数数组P [1..n],我们要构建一个数组S [1..n]:
在P [1..i-1]中比P [i]大的成员中,我们选择具有最大索引的P [k](1 <= k
显然,S []中的第一个元素将为0,因为之前没有元素。其他人可以通过数组P []的迭代找到,但是,这将是O(n^2)
,因为它是系列1+2+...+n=[1/2n(n+1)]
的总和。
有没有办法在线性时间内完成此操作?我已经考虑过使用 stacks ,因为它有助于提取具有更大值的最高索引,但是,我试图实现它的任何方式仍然需要我通过创建的堆栈,所以它是实际上更糟糕 - 创建堆栈的时间,以及到达所需元素的时间,一遍又一遍。也许还有另一种方式?
有关如何完成的任何想法/建议/提示?
示例:
P[5,4,9,7,8]-->S[0,5,0,9,9]
P[1,5,2,3]-->S[0,0,5,5]
澄清:
我们应该为S [i]指定最高索引数字,仍然大于P [1..i-1]中的P [i]。例如,假设P [8,2,1]。虽然8是最大值,但S [3]将保持值2,因为它是仍然大于P [3]的最高索引数。 - &GT; S [0,8,2]
修改
我相信我有一个O(n)解决方案,使用堆栈。伪代码的想法:
BuildS(P[])
Temp-StackNIL
for(i<--1 up to n)
while(Temp-Stack≠NIL)
if(P[i]<=top[Temp-Stack])
pop(Temp-Stack) //goes back to while
else
S[i]<--top[Temp-Stack]
push(Temp-Stack,P[i]) //goes back to for
S[i]<--0 //out of while
push(Temp-Stack,P[i]) //goes back to for
我说得对吗?
答案 0 :(得分:2)
我认为没有O(n)解决方案,尽管我提出了O(n log n)。
假设我们有binary search tree(BST)。主循环伪代码:
for i in [0, len(P)):
S[i] = BST.search(P[i])
BST.insert(P[i], i)
我认为search
会为S[i]
返回P[i]
。
def search(value):
def getSbyIndex(index):
return index == -inf ? 0 : P[index]
curVertex = BST.root
maxIndex = -inf
while:
if curVertex.value > value:
if !(curVertex.leftChild exists):
return getSbyIndex(maxIndex)
else:
maxIndex = max(maxIndex, curVertex.index, curVertex.rightChild.subtreeMaxIndex)
if curVertex.leftChild.value <= value:
return getSbyIndex(maxIndex)
else:
curVertex = curVertex.leftChild
else:
if !(curVertex.rightChild exists):
return getSbyIndex(maxIndex)
else:
curVertex = curVertex.rightChild
为了简单起见,我写了search
未优化(并且也没有检查一些不存在的顶点情况,为了简单起见,小心!),以便给出一般的想法。我们从BST的根开始,在需要时更新maxIndex
的常规规则(请参阅下面的说明)。我们BST的每个叶子(实际上代表一些P [x])包含5个字段:
那么什么时候需要?假设我们有curVertex.value <= value
。这意味着我们必须转到正确的子树。左子树的任何vertex.value
也是<= value
,因此左子树和当前顶点中没有顶点(P[y]
),因此满足P[y] > P[new]
条件,因此我们不会更改maxIndex
。
同样地,让我们假设我们有curVertex.value > value
,它将我们引向左侧子树。但是这次右侧子树的任何vertex.value
都是vertex.value > value
,因此当前和右侧子树顶点中的所有P[y]
实际上都大于P[new]
,所以我们必须找到它们的最大索引,等于max(curVertex.index,curVertex.rightChild.subtreeMaxIndex),并尝试用它更新maxIndex
。
我们需要的最后一件事是insert
。
def insert(value, index):
newVertex = BST.insertNode(value)
newVertex.index = index
curVertex = newVertex
while curVertex is not BST.root:
curVertex.subtreeMaxIndex = max(curVertex.index, curVertex.leftChild.subtreeMaxIndex, curVertex.rightChild.subtreeMaxIndex)
curVertex = curVertex.parent
在这里,我没有再检查孩子是否存在,还添加了parent
字段。 BST.insertNode
只是一个基本的BST插入方法,它返回一个新的顶点对象。之后,我们只需向上移动到根,为路径上的每个顶点更新.subtreeMaxIndex
。
总的来说,对于n
和log n
调用,我们对主循环insert
进行了search
次迭代,因此最终的复杂度为O(n log n)。
答案 1 :(得分:1)
O(n)
我们的想法是在循环P
时跟踪遇到的最高值,并将P[i]
与此值进行比较。
这是我提出的伪代码(使用你的第一个例子)
P = [1,5,2,3]
S = []
highest = 0
for i in P
if highest < P[i]
highest = P[i]
S[i] = 0
else
S[i] = highest
我在这里假设你只使用值&gt; = 0但是如果你得到负值highest
应该用尽可能小的值初始化。