面试 - 为每个数组元素找到更多元素

时间:2013-11-06 06:06:59

标签: arrays algorithm compare

在采访中我被问到以下问题(不幸的是我找不到比N ^ 2更好的答案)

对于大小为N的arr的给定数组unsigned int,对于每个元素(在索引i中),我应该返回索引j中的一个元素(j > i),arr[j] > arr[i] 即我应该返回数组res,其中res [i]有一个arr [j],j> i,arr [j]> arr [i],j在所有索引k中是min,使得arr [k]> ARR [I] 例如

arr[] = {3,1,4,2,5,7};
res[] = {2,2,4,4,5,-1};//-1 says no such index

是否有更好的时间复杂性? 感谢

3 个答案:

答案 0 :(得分:6)

O(N)时间和O(N)空间复杂度:

创建空堆栈,从右侧迭代数组

每个迭代项的

: 只要顶部的项目小于当前项目,就会从堆栈中弹出,然后如果堆栈变空,则右侧没有更大的元素,如果不是,那么右边的第一个更大的项目是当前元素,推送当前元素堆

void GetFirstRight(int* arr, int size, int* res){
  stack<int> s;
  for (int i = size - 1; i >= 0; --i) {
    while (!s.empty() && s.top() <= arr[i]) s.pop();
    if (s.empty()) { 
      res[i] = -1;
    } else {
      res[i] = s.top();
    }
    s.push(arr[i]);
  }
}

答案 1 :(得分:3)

O(n)算法:

维护一堆仍未解决的索引。这将进行排序,以便最小的仍未解决的值位于顶部。当您从堆栈中弹出一个新元素时,直到新元素的值小于堆栈顶部的值。对于您弹出的每个,答案是当前索引。然后推送当前索引。最后,堆栈中任何内容的结果都是-1。

代码(C ++):

stack<int> unsolved;
int arr[] = {3,1,4,2,5,7}, N = 6;
int res[1234];

int main() {
    for (int i = 0; i < N; i++) {
        while (!unsolved.empty() && arr[unsolved.top()] < arr[i]) {
            res[unsolved.top()] = i;
            unsolved.pop();
        }
        unsolved.push(i);
    }
    while (!unsolved.empty()) {
        res[unsolved.top()] = -1;
        unsolved.pop();
    }
    // Print results
    for (int i = 0; i < N; i++) printf("%d%c", res[i], i==N-1 ? '\n' : ' ');

    return 0;
}

输出:

2 2 4 4 5 -1

答案 2 :(得分:0)

保持并行数组 b 。 make b [0] = 0 。 通过 a 的元素进行迭代。随着你的进展,将 b 的值设置为 a 的连续单元格的差异。

所以,如果

a[0]=9
a[1]=4
a[2]=17
a[3]=2
a[4]=3
a[5]=6
a[6]=0
a[7]=3
a[8]=1
a[9]=1
a[10]=7

然后,

b[0]=0
b[1]=-5
b[2]=13
b[3]=-15
b[4]=1
b[5]=3
b[6]=-6
b[7]=3
b[8]=-2
b[9]=0
b[10]=6

您应该关注的是 b 数组中的( - )单元格。 现在,开始在数组 b 上向后迭代 - 从开始 b [10] 在上面的例子中。 保持 currentMax 值。最初设置为第一个最大值(+) 在数组上 - 你无法对数组末尾的( - )条目做任何事情。 当您从 b [b.length] 向后迭代到 b [0] 时,请执行以下操作:

更新 currentMax

currentMax += <value at the current cell of **b**>

如果(currentMax&lt; 0)那么/ *你已经点击了没有索引的元素* /然后继续前进,直到你找到一个正 b [i] 输入,当您找到一个时,将 currentMax 的值设置为它。

(+) currentMax 的值表示重置 currentMax 的单元格是所有访问过的单元格的索引的单元格,所以( - )值不是 - 索引单元格。

在上面的例子中,7 a [10] a [3] ... a [9] 中的所有指数,因为 - currentMax 是在单元格10初始化的(并且之后不会重置) - 所有这些添加之后 currentMax 的值仍然是(+)一直到单元格4(单元格4反映了从单元格3到4的变化)

b [3] 时, currentMax 低于0 - 表示单元格2没有索引。 在 b [2] 处找到的值为正,而 currentMax 为负值 - 因此在b [3], currentMax = 13 处进行迭代并迭代上。

数组大小中的线性 - 需要 O(n)时间。