Arrays 算法:对于数组的每个元素,找出其左侧的最大值,并小于其本身

Arrays 算法:对于数组的每个元素,找出其左侧的最大值,并小于其本身,arrays,algorithm,Arrays,Algorithm,例如,给定一个数组: [1, 2, 5, 4, 2, 6, 7, 3] 找出每个元素左侧的最大值并小于其自身(如果不存在此类元素,则为-1): 最佳算法是什么?是否有比O(n*log(n))更好的算法?Bruteforce算法迭代数组,逐个搜索访问的元素并与当前元素进行比较。因此这就是O(n^2)算法 加快搜索过程的关键是搜索部分。我们必须充分利用我们已经知道的,也就是我们访问过的元素 那么基本算法如下所示: magic = new magic_data_structure result =

例如,给定一个数组:

[1, 2, 5, 4, 2, 6, 7, 3]
找出每个元素左侧的最大值并小于其自身(如果不存在此类元素,则为-1):


最佳算法是什么?是否有比
O(n*log(n))
更好的算法?

Bruteforce算法迭代数组,逐个搜索访问的元素并与当前元素进行比较。因此这就是
O(n^2)
算法

加快搜索过程的关键是搜索部分。我们必须充分利用我们已经知道的,也就是我们访问过的元素

那么基本算法如下所示:

magic = new magic_data_structure
result = []
for x in input_array:
    y = magic.find_largest_but_less_than_current(x)
    result.push(y)
    magic.inesrt(x)
因此,我们需要一种具有插入和搜索复杂性
O(logn)
的数据结构。这通常是一个平衡的搜索树。例如,我们可以使用红黑树

<> P>为了简化,我们可以从C++ STL使用<代码> SET/COM>。有关更多详细信息,请参阅以下代码

示例链接:

#包括
使用名称空间std;
使用vi=向量;
设置s;
维孚(维康与a){
vi ret;
s、 清除();
用于(自动常数x:a){
自动it=s.下限(x);
如果(it!=开始){
it=上一个(it);
重新推后(*it);
}否则{
反向推回(-1);
}
s、 插入(x);
}
返回ret;
}
int main(){
vi a={1,2,5,4,2,6,7,3};
vi b=foo(a);
对于(自动x:b)printf(“%d”,x);put(“”);
返回0;
}


Bruteforce算法迭代数组,逐个搜索访问的元素并与当前元素进行比较。因此这就是
O(n^2)
算法

加快搜索过程的关键是搜索部分。我们必须充分利用我们已经知道的,也就是我们访问过的元素

那么基本算法如下所示:

magic = new magic_data_structure
result = []
for x in input_array:
    y = magic.find_largest_but_less_than_current(x)
    result.push(y)
    magic.inesrt(x)
因此,我们需要一种具有插入和搜索复杂性
O(logn)
的数据结构。这通常是一个平衡的搜索树。例如,我们可以使用红黑树

<> P>为了简化,我们可以从C++ STL使用<代码> SET/COM>。有关更多详细信息,请参阅以下代码

示例链接:

#包括
使用名称空间std;
使用vi=向量;
设置s;
维孚(维康与a){
vi ret;
s、 清除();
用于(自动常数x:a){
自动it=s.下限(x);
如果(it!=开始){
it=上一个(it);
重新推后(*it);
}否则{
反向推回(-1);
}
s、 插入(x);
}
返回ret;
}
int main(){
vi a={1,2,5,4,2,6,7,3};
vi b=foo(a);
对于(自动x:b)printf(“%d”,x);put(“”);
返回0;
}


<什么编程语言?@ RoPMurkHelpHelf任何你喜欢的C++、Ruby、java……<代码> O(n log n)< /C>算法看起来是什么样的?一个简单的算法会产生一个运行时界
O(n^2)
@David,我认为如果你提供这个问题的当前解决方案,并将这个问题转移到代码审查站点,会更好。很抱歉,这个问题描述得很糟糕。谢谢大家的建议。我将阅读指南,以便将来更好地提问。:)什么编程语言?@ RoopPrEkHelpHelf任何你喜欢的C++、Ruby、java……<代码> O(n log n)< /C>算法看起来是什么样的?一个简单的算法会产生一个运行时界
O(n^2)
@David,我认为如果你提供这个问题的当前解决方案,并将这个问题转移到代码审查站点,会更好。很抱歉,这个问题描述得很糟糕。谢谢大家的建议。我将阅读指南,以便将来更好地提问。:)太棒了,太清楚了!我不希望有这么快、简洁的可运行代码。:)@大卫,欢迎来到SO。你应该期待从这个庞大而有才华的社区快速回复。“delta”,你写的一个非常好的C++代码。非常感谢。太棒了,太清楚了!我不希望有这么快、简洁的可运行代码。:)@大卫,欢迎来到SO。你应该期待从这个庞大而有才华的社区快速回复。“delta”,你写的一个非常好的C++代码。非常感谢。
#include <bits/stdc++.h>
using namespace std;

using vi = vector <int>;

set <int> s;

vi foo(vi const &a) {
    vi ret;
    s.clear();
    for (auto const x: a) {
        auto it = s.lower_bound(x);
        if (it != begin(s)) {
            it = prev(it);
            ret.push_back(*it);
        } else {
            ret.push_back(-1);
        }
        s.insert(x);
    }
    return ret;
}

int main() {
    vi a = {1, 2, 5, 4, 2, 6, 7, 3};
    vi b = foo(a);
    for (auto x: b) printf("%d ", x); puts("");
    return 0;
}