假设给定一个整数数组A,我想找到另一个使用A的COUNT数组。
例如,int A [] = {34,10,15,14,30,27,21,32,50}
对于上面的例子,COUNT []应该是:{0,0,1,0,3,0,0,6,8}
这里,COUNT [i]对应于A [i],COUNT [i]表示A的连续先前元素的数量小于A [i]。
例如,A [1] = 10,COUNT [1] = 0,因为A中没有先前的元素小于A [1]。A [7] = 32,COUNT [7] = 6,因为32大于前6个连续元素(例如10,15,14,30,27,21)。
我们可以为这个问题找到O(n)解决方案吗?
修改
根据@ user1990169&#39的算法, 我在Java中实现它如下,但由于算法不计算堆栈上不存在的那些索引(在早期迭代中已经弹出),它没有给出预期的输出。
public static void main(String[] args) throws Exception {
Stack<Integer> stack = new Stack<Integer>();
// int a[] = new int[] { 53, 2, 7, 5, 15, 12, 10, 38, 72 };
int a[] = new int[] { 34, 10, 15, 14, 30, 27, 21, 32, 50 };
int N = a.length;
int[] count = new int[N];
int tos = 0;
int poppedElemIdx = 0;
int popCount = 0;
boolean counted = false;
stack.clear();
for (int i = 0; i < N; i++) {
popCount = 0;
counted = false;
while (!stack.isEmpty()) {
tos = stack.peek();
if (a[tos] > a[i]) {
stack.push(i);
count[i] = count[poppedElemIdx] + popCount;
counted = true;
break;
}
poppedElemIdx = stack.pop();
popCount++;
// popCount += (count[poppedElemIdx] + 1);
}
if (counted) {
continue;
}
stack.push(i);
count[i] = popCount;
}
// Print count array
for (int i = 0; i < N; i++) {
System.out.print(count[i] + " ");
}
}
答案 0 :(得分:4)
O(N)空间和O(N)时间复杂度算法。
从左到右遍历数组。保持外部堆栈元素。
A[0] = 34, push 34 onto stack. Count[0] = 0.
A[1] = 10,
Now keep popping out from stack till either it is empty
or you encounter a number greater than the current element (10).
Here 34 is > 10, hence we push 10 onto stack and make Count[1] = 0.
A[2] = 15.
So we pop out 10 from the stack, push 15 onto stack,
and make Count[2] = Count[ last popped out index ] + Number of indices popped out
= 0 + 1 = 1.
A[3] = 14.
So we push 14 onto stack and make Count[3] = 0.
A[4] = 30.
So we pop out 14 and 15 from the array, push 30 onto the array
and make Count[4] = Count[ index of 15 ] + Number of indices popped out(2)
= 1 + 2 = 3.
这样做直到你到达阵列的末尾。
由于每个项目只被推入一次并从堆栈中弹出一次,因此时间复杂度为O(2 * N)= O(N)。
编辑:正如所建议的那样,如果将索引存储在堆栈中而不是值,那会更好。
答案 1 :(得分:0)
对原始算法进行少量修改后的工作程序:
public static void main(String[] args) throws Exception {
Stack<Integer> stack = new Stack<Integer>();
int a[] = new int[] { 53, 2, 7, 5, 15, 12, 10, 38, 72 };
// int a[] = new int[] { 34, 10, 15, 14, 30, 27, 21, 32, 50 };
int N = a.length;
int[] count = new int[N];
int tos = 0;
int poppedElemIdx = 0;
int popCount = 0;
boolean counted = false;
stack.clear();
for (int i = 0; i < N; i++) {
popCount = 0;
counted = false;
while (!stack.isEmpty()) {
tos = stack.peek();
if (a[tos] > a[i]) {
stack.push(i);
count[i] = popCount;
counted = true;
break;
}
poppedElemIdx = stack.pop();
popCount += (count[poppedElemIdx] + 1);
}
if (counted) {
continue;
}
stack.push(i);
count[i] = popCount;
}
// Print count array
for (int i = 0; i < N; i++) {
System.out.print(count[i] + " ");
}
}