最大。大于给定数字的数字的距离

时间:2013-10-14 07:51:44

标签: arrays algorithm

我正在经历一个面试问题..并提出了需要找到的逻辑:

  

为大于ja[j])的元素a[i]查找索引j < i,以使(i-j)最大。我想为数组中的每个索引j找到iO(n)O(n log n)时间O(n)额外空格。

到目前为止我做了什么:

1)O(n^2)使用简单的for loop s

2)建立平衡的B.S.T.当我们从左到右扫描元素时,对于i'元素,查找元素的索引大于它。但我意识到单个元素很容易O(n),因此对整个数组来说O(n^2)

我想知道是否可以在O(n)O(n log n)中执行此操作。如果是,请提供一些提示。

编辑:我想我无法解释我的问题。让我清楚地解释一下: 我希望arr[j]左侧arr[i] (i-j)arr[j]>arr[i]是最大的for(i=0 to n-1).{2,3,1,6,0}找到所有索引i,即for 2 , ans=-1

编辑2:示例 - for 3 , ans=-1
for 1 , ans=2
for 6 , ans=-1
for 0 , ans=4(i-j)==(2-0)
{{1}}
{{1}}(i-j)==(4-0)

4 个答案:

答案 0 :(得分:12)

创建一个最大辅助数组,让它为maxs,它基本上包含阵列上的最大值,直到当前索引。

正式:maxs[i] = max { arr[0], arr[1], ..., arr[i] }

请注意,这是预处理步骤,可以在O(n)

中完成

现在,对于每个元素i,您正在寻找maxs中比arr[i]更大的第一个元素。这可以使用二进制搜索来完成,并且每个操作都是O(logn)

总共提供O(nlogn)时间和O(n)额外空间。

答案 1 :(得分:2)

您可以在O(n)时间内使用您尚未找到解决方案的数组索引的堆栈数据结构来执行此操作。它可以实现为最多n个元素的数组。

从最左边的元素开始,从左到右迭代输入数组:

  • 弹出数组元素小于当前元素的堆栈中的所有索引。将当前元素的索引标记为您弹出的每个索引的解决方案。
  • 推送当前元素的索引。

不变:与堆栈中索引对应的数组项始终按升序排列,最少的项位于顶部。

当您到达输入的开头时,使用-1标记仍然保留在堆栈中的所有项目;对他们来说没有答案。

每个数组索引只被压入堆栈一次并且最多弹出一次,因此该算法在O(n)时间内运行。

Python中的一个例子:

def solution(arr):
    stack = []
    out = [-1]*len(arr)
    for i in xrange(len(arr)-1, -1, -1):
        while len(stack) > 0 and arr[stack[-1]] < arr[i]:
            out[stack.pop()] = i
        stack.append(i);
    return out

请注意,输入[2, 4, 1, 5, 3]的正确答案为[-1, -1, 1, -1, 3]:对于固定的i,当j最大时差异ji最大,因此您正在寻找最左侧 index j,最小化距离。 (当j

答案 2 :(得分:0)

我能想到的最快的解决方案是分配第二个阵列并从左到右扫描阵列。当您遍历数组并扫描每个元素时,如果arr [index]大于第二个数组的最右侧元素,则将元素的索引附加到第二个数组。这是每个附加的O(1)时间,最多n个附加,所以O(n)。

最后,一旦您的阵列完成,请再次通过您的阵列。对于每个元素,使用二进制搜索扫描您的第二个数组(这是可能的,因为它是隐式排序的)并找到数组中最左边(最早插入的)索引j,使得arr [j]&gt; ARR [i]中。

为此,您必须修改二进制搜索。如果你找到一个索引j,那么arr [j]&gt; arr [i],你仍然需要检查左边是否有任何索引k,这样arr [k]&gt; ARR [i]中。您必须这样做,直到找到最左侧的索引。

认为这是每个二进制搜索的O(log n),你必须搜索n个元素。因此,总时间复杂度将接近于O(n log n),但我不确定这一点。对此答案的任何意见/建议将不胜感激。

答案 3 :(得分:0)

这是我在C ++中的解决方案
我们维持不断增加的数量。比较当前元素和数组后面的元素。 如果到目前为止,它大于或等于larget元素,则将该元素附加到数组中,返回-1,左侧没有较小的元素。

如果不是,我们使用二进制搜索,找到索引并返回差值。 (我们仍然需要将vec.back()附加到数组,因为我们无法更改索引)

int findIdx(vector<int>& vec, int target){
    auto it = upper_bound(vec.begin(), vec.end(), target);
    int idx = int(it-vec.begin());
    return idx;
}

vector<int> farestBig(vector<int>& arr){
    vector<int> ans{-1};
    vector<int> vec{arr[0]};
    int n = (int)arr.size();
    for(int i=1; i<n; i++){
        if(arr[i] >= vec.back()){
            ans.push_back(-1);
            vec.push_back(arr[i]);
        }
        else{
            int idx = findIdx(vec, arr[i]);
            ans.push_back(i-idx);
            vec.push_back(vec.back());
        }
    }
    return ans;
}