【问题标题】:Finding maximum values of rests of array查找数组其余部分的最大值
【发布时间】:2013-05-08 20:29:00
【问题描述】:

例如:

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
                         ...??
                      }
                  }
             }
         }

【问题讨论】:

  • 你能使用标准库中的算法吗?
  • @yngum- OP 特别想要数组中第一个最大值之后的最大值。前四个值可能都在数组中的最大值之前。
  • @templatetypedef:实际上是不可能,因为最大值是前四个值之一,因此它不能是before 本身。但除了技术性......:P

标签: c++ arrays recursion max dynamic-arrays


【解决方案1】:

这就是您在 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;
    }
}

这是live example。

【讨论】:

  • 我很抱歉,你是对的。我很抱歉!但是,在最坏的情况下(给定一个降序),这会在 O(n^2) 时间内运行,这对于大输入来说是不利的。
  • @templatetypedef:抱歉,删除了之前的评论,您对复杂性的看法是正确的。不过,在我看来,这个算法简单易懂,所以除非最坏情况的复杂性被证明是一个问题,否则它是一个很好的选择。
【解决方案2】:

这是使用Cartesian tree 数据结构的好地方。笛卡尔树是由具有以下属性的元素序列构建的数据结构:

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

例如,给定序列

4  1  0  3  2

笛卡尔树是

   4
    \
     3
    / \
   1   2
    \
     0

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

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

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

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    如果你可以修改数组,你的代码会变得更简单。每当您找到一个最大值时,将其输出并将其在原始数组中的值更改为某个较小的数字,例如 -MAXINT。一旦你输出了数组中元素的数量,你就可以停止你的迭代。

    【讨论】:

    • 您基本上描述了一种异地选择排序,根本不是 OP 想要的。
    【解决方案4】:
    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 之后的所有元素,因为 I 是从 G 开始到我们搜索到的最大元素至今。然后我们将 I 附加到output。重复直到输入数组用完为止。

    【讨论】:

    • 看起来不错,但我不知道数据结构和对象。实际上我的目的是展示建筑物的轮廓取决于视点。 p1305.hizliresim.com/19/9/mw3mn.png 使用指针并在运行时动态分配内存。使用适当的指针算法来访问建筑物。不要使用数组和数组索引。所以没有对象或数据结构一切都很好,直到写建筑物的高度,我无法制作算法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2017-06-30
    • 1970-01-01
    • 2016-02-24
    • 2021-09-15
    相关资源
    最近更新 更多