未排序的数组,为每个元素找到下一个更大的元素,否则打印 -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
是偶数还是奇数,创建几个迭代器 first
和 last
,并用它们调用模板化的 next_greater
迭代器和要比较的值,n
.
- 模板化的
next_greater
排序 [first
, last
) 然后使用 upper_bound 到 return 第一个大于 [=16 的元素=].
#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
要求有点复杂 假设我们有一个未排序的数组,例如:{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
是偶数还是奇数,创建几个迭代器first
和last
,并用它们调用模板化的next_greater
迭代器和要比较的值,n
.- 模板化的
next_greater
排序 [first
,last
) 然后使用 upper_bound 到 return 第一个大于 [=16 的元素=].
#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