【问题标题】:unsorted array, find the next greater element for every element, else print -1未排序的数组,为每个元素查找下一个更大的元素,否则打印 -1
【发布时间】:2021-12-30 21:35:39
【问题描述】:

要求有点复杂 假设我们有一个未排序的数组,例如:{12, 72, 93, 0, 24, 56, 102}

如果我们有一个奇数位置,我们必须寻找他右边的下一个更大的元素,假设我们取 v[1] = 12,'12' 的 nge 是 24;

但是如果我们有一个偶数位置,我们必须在他的左边寻找下一个更大的元素,假设我们取 v[2] = 72,没有大于 '72' 的数字,所以我们将打印'-1';再举个例子,v[4] = 0,'0'的nge是12;

输出应该是:24 -1 102 12 56 72 -1

我试图在 C++ 中解决这个问题:

#include <iostream>
using namespace std;

int main() {
    const int CONST = 10000;
    int n, v[CONST];
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> v[i];
    }
    for (int i = 1; i <= n; i++) {
        int next = -1;
        if (i % 2 != 0) {   
            for (int j = i + 1; j <= n; j++) {
                if (v[j] > v[i]) {
                    next = v[j];
                    break;
                }
            }
            cout << next << " ";
        }
        else {                
            for (int k = 1; k <= i - 1; k++) {
                if (v[k] > v[i]) {
                    next = v[k];
                    break;
                }
            }
            cout << next << " ";
        }
    }
    return 0;
}

首先,我认为我必须对数组进行排序,然后使用二进制搜索来查找下一个更大的元素

【问题讨论】:

  • 您的输出取决于元素未排序的相对位置。即使好处不明显,我通常也会默认对容器进行分类 - 所以我在这里说“不要对那个容器进行分类!”很奇怪
  • @alexander s C++中数组的索引从0开始。所以数组的第一个元素的位置是偶数。:)
  • @vlad 因为他们的问题和示例的措辞,索引从 1 开始。
  • @JohnFilleau 尽管如此,程序索引应从 0 开始。
  • 您对“下一个更大”的搜索在找到下一个大于时会中断。您需要遍历所有(没有break)才能找到差异最小的那个。

标签: c++ algorithm for-loop vector max


【解决方案1】:

对于初学者而不是数组,最好声明std::vector&lt;int&gt; 类型的对象。

注意 C++ 中的索引从 0 开始。

在这个if语句中

            if (v[j] > v[i]) {
                next = v[j];
                break;
            }

一旦找到大于当前的第一个元素,您就会退出循环。很明显,这种做法是错误的。

我可以建议以下解决方案。

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v;
    size_t n = 0;

    std::cin >> n;

    v.resize( n );

    for (auto &item : v)
    {
        std::cin >> item;
    }

    for (size_t i = 0, n = v.size(); i < n; i++)
    {
        size_t next = i;

        if (i % 2 == 0)
        {
            for (size_t j = i + 1; j != n; ++j)
            {
                if (v[i] < v[j] && ( next == i || v[j] < v[next] ))
                {
                    next = j;
                }
            }
        }
        else
        {
            for (size_t j = i; j-- != 0; )
            {
                if (v[i] < v[j] && ( next == i || v[j] < v[next] ))
                {
                    next = j;
                }
            }
         }

         std::cout << ( next != i ? v[next] : -1 ) << ' ';
    }
}

程序输出可能看起来像

7
12 72 93 0 24 56 102
24 -1 102 12 56 72 -1

【讨论】:

    【解决方案2】:

    如果您正在寻找简单但效率不高的东西(例如 O(n) 空间复杂度 - 向量复制 - 和 O(nlogn) 时间复杂度 - 排序加搜索 - 而不是 O( n) 对于线性搜索),这是一个选项:

    • next_greater 检查 pos 是偶数还是奇数,创建几个迭代器 firstlast,并使用这些迭代器和要比较的值 n 调用模板化的 next_greater
    • 模板化的next_greater 对[first, last) 进行排序,然后使用upper_bound 返回大于n 的第一个元素。

    [Demo]

    #include <algorithm>  // upper_bound
    #include <iostream>  // cout
    #include <utility>  // pair
    #include <vector>
    
    template <typename InputIt, typename T>
    T next_greater(InputIt first, InputIt last, T n)
    {
        std::sort(first, last);
        auto it{ std::upper_bound(first, last, n) };
        if (it == last) { return -1; }
        return *it;
    }
    
    int next_greater(std::vector<int> v, size_t pos)
    {
        using it = std::vector<int>::iterator;
        using pair_it = std::pair<it, it>;
    
        auto [first, last] { (pos % 2 == 1)
            ? pair_it{ std::begin(v), std::begin(v) + pos }  // [begin, pos)
            : pair_it{ std::begin(v) + pos + 1, std::end(v) }  // [pos + 1, end)
        };
        return next_greater(first, last, v[pos]);  
    }
    
    int main()
    {
        const std::vector<int> v{12, 72, 93, 0, 24, 56, 102};
        std::cout << "Next greater for i(n):\n";
        for (size_t i{0}; i < v.size(); ++i)
        {
            std::cout << "\t" << i << "(" << v[i] << "): " << next_greater(v, i) << "\n";
        }
    }
    
    // Outputs:
    //
    //   Next greater for i(n):
    //      0(12): 24
    //      1(72): -1
    //      2(93): 102
    //      3(0): 12
    //      4(24): 56
    //      5(56): 72
    //      6(102): -1
    

    【讨论】:

      猜你喜欢
      • 2013-11-17
      • 2014-07-28
      • 1970-01-01
      • 2014-04-09
      • 2021-10-13
      • 2022-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多