未排序的数组,为每个元素找到下一个更大的元素,否则打印 -1

unsorted array, find the next greater element for every element, else print -1

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

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

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

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

对于初学者而不是数组,声明类型 std::vector<int>.

的对象要好得多

注意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

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

  • next_greater 检查 pos 是偶数还是奇数,创建几个迭代器 firstlast,并用它们调用模板化的 next_greater迭代器和要比较的值,n.
  • 模板化的 next_greater 排序 [first, last) 然后使用 upper_bound 到 return 第一个大于 [=16 的元素=].

[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