查找数组其余部分的最大值

Finding maximum values of rests of array

本文关键字:最大值 余部 数组 查找      更新时间:2023-10-16

例如:

array[] = {3, 9, 10, **12**,1,4,**7**,2,**6**,***5***}
首先,我需要最大值=

12,然后我需要数组其余部分(1,4,7,2,6,5(中的最大值,所以值=7,然后数组6其余部分的最大值,然后是5,之后,我将需要一系列这个值。 这回馈 (12,7,6,5(。

如何获得这些数字?我尝试了以下代码,但它似乎是无限的我想我需要一个递归函数,但我该怎么做呢?

max=0; max2=0;...
   for(i=0; i<array_length; i++){
             if (matrix[i] >= max)
                max=matrix[i];
             else {
                  for (j=i; j<array_length; j++){
                      if (matrix[j] >= max2)
                      max2=matrix[j];
                      else{
                       ...
                        ...for if else for if else
                         ...??
                      }
                  }
             }
         }
以下是

您在 C++11 中使用 std::max_element() 标准算法执行此操作的方式:

#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
    int arr[] = {3,5,4,12,1,4,7,2,6,5};
    auto m = std::begin(arr);
    while (m != std::end(arr))
    {
        m = std::max_element(m, std::end(arr));
        std::cout << *(m++) << std::endl;
    }
}

这是一个活生生的例子

这是使用笛卡尔树数据结构的绝佳位置。 笛卡尔树是由具有以下属性的一系列元素构建的数据结构:

  • 笛卡尔树是一棵二叉树。
  • 笛卡尔树
  • 服从堆属性:笛卡尔树中的每个节点都大于或等于其所有后代。
  • 笛卡尔树的无序遍历返回原始序列。

例如,给定序列

4  1  0  3  2

笛卡尔树将是

   4
    
     3
    / 
   1   2
    
     0

请注意,这服从堆属性,并且无序遍历返回序列4 1 0 3 2,这是原始序列。

但这里有一个关键的观察结果:请注意,如果你从这棵笛卡尔树的根部开始,然后开始向右走,你会得到数字4(序列中最大的元素(,然后是3(4之后最大的元素(和数字2(3之后的最大元素(。 更一般地说,如果你为序列创建一个笛卡尔树,然后从根开始,继续向右走,你会得到你正在寻找的元素序列!

这样做的美妙之处在于,笛卡尔树可以在时间Θ(n(中构建,这是非常快的,沿着脊柱走只需要O(n(的时间。 因此,找到您要查找的序列所需的总时间为 Θ(n(。 请注意,如果输入按降序排序,则在最坏的情况下,"找到最大的元素,然后找到子数组中出现的最大元素,等等"的方法将在时间 Θ(n2( 上运行,因此此解决方案要快得多。

希望这有帮助!

如果你可以修改数组,你的代码将变得更加简单。 每当找到 max 时,输出该值并将其在原始数组中的值更改为一些小数字,例如 -MAXINT。 输出数组中的元素数后,可以停止迭代。

std::vector<int> output;
for (auto i : array)
{
    auto pos = std::find_if(output.rbegin(), output.rend(), [i](int n) { return n > i; }).base();
    output.erase(pos,output.end());
    output.push_back(i);
}

希望你能理解这段代码。 我更擅长用C++编写算法,而不是用英语描述它们,但这里有一个尝试。

在我们开始扫描之前,output是空的。 这是空输入的正确状态。

我们首先查看输入数组的第一个未查看的元素I。 我们向后扫描输出,直到找到大于 I 的元素G。然后我们从G之后的位置开始擦除。 如果我们没有找到,这意味着I是迄今为止我们搜索过的元素中最大的元素,因此我们擦除了整个output。 否则,我们会在G之后擦除每个元素,因为 G到我们迄今为止搜索的内容I是最伟大的。 然后我们将I附加到output. 重复直到输入数组耗尽。