📜  寻找下一个更大元素的 C 程序

📅  最后修改于: 2022-05-13 01:57:09.106000             🧑  作者: Mango

寻找下一个更大元素的 C 程序

给定一个数组,打印每个元素的下一个更大元素 (NGE)。元素 x 的下一个更大元素是数组中 x 右侧的第一个更大元素。对于不存在更大元素的元素,将下一个更大的元素视为-1。

例子:

  1. 对于数组,最右边的元素总是具有下一个更大的元素为 -1。
  2. 对于按降序排序的数组,所有元素的下一个较大元素为 -1。
  3. 对于输入数组 [4, 5, 2, 25],每个元素的下一个更大的元素如下。
Element       NGE
   4      -->   5
   5      -->   25
   2      -->   25
   25     -->   -1

d)对于输入数组 [13, 7, 6, 12},每个元素的下一个更大的元素如下。

Element        NGE
   13      -->    -1
   7       -->     12
   6       -->     12
   12      -->     -1

方法1(简单)
使用两个循环:外部循环一一挑选所有元素。内循环为外循环选取的元素寻找第一个更大的元素。如果找到更大的元素,则将该元素打印为下一个,否则打印-1。

下面是上述方法的实现:

C
// Simple C program to print next greater elements
// in a given array
#include
  
/* prints element and NGE pair for all elements of
arr[] of size n */
void printNGE(int arr[], int n)
{
    int next, i, j;
    for (i=0; i


C
// A Stack based C program to find next 
//  greater element for all array elements.
#include 
#include 
#include 
#define STACKSIZE 100
  
// stack structure
struct stack {
    int top;
    int items[STACKSIZE];
};
  
// Stack Functions to be used by printNGE()
void push(struct stack* ps, int x)
{
    if (ps->top == STACKSIZE - 1) {
        printf("Error: stack overflown");
        getchar();
        exit(0);
    }
    else {
        ps->top += 1;
        int top = ps->top;
        ps->items[top] = x;
    }
}
  
bool isEmpty(struct stack* ps)
{
    return (ps->top == -1) ? true : false;
}
  
int pop(struct stack* ps)
{
    int temp;
    if (ps->top == -1) {
        printf("Error: stack underflow n");
        getchar();
        exit(0);
    }
    else {
        int top = ps->top;
        temp = ps->items[top];
        ps->top -= 1;
        return temp;
    }
}
  
/* prints element and NGE pair for all elements of
arr[] of size n */
void printNGE(int arr[], int n)
{
    int i = 0;
    struct stack s;
    s.top = -1;
    int element, next;
  
    /* push the first element to stack */
    push(&s, arr[0]);
  
    // iterate for rest of the elements
    for (i = 1; i < n; i++) {
        next = arr[i];
  
        if (isEmpty(&s) == false)
        {
            // if stack is not empty, then pop an element
            // from stack
            element = pop(&s);
  
            /* If the popped element is smaller than next,
               then a) print the pair b) keep popping while
               elements are smaller and stack is not empty
             */
            while (element < next) {
                printf("n %d --> %d", element, next);
                if (isEmpty(&s) == true)
                    break;
                element = pop(&s);
            }
  
            /* If element is greater than next, then push
               the element back */
            if (element > next)
                push(&s, element);
        }
  
        /* push next to stack so that we can find
           next greater for it */
        push(&s, next);
    }
  
    /* After iterating over the loop, the remaining
       elements in stack do not have the next greater
       element, so print -1 for them */
    while (isEmpty(&s) == false)
    {
        element = pop(&s);
        next = -1;
        printf("n %d --> %d", element, next);
    }
}
  
/* Driver code */
int main()
{
    int arr[] = { 11, 13, 21, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printNGE(arr, n);
    getchar();
    return 0;
}


输出
11 -- 13
13 -- 21
21 -- -1
3 -- -1

时间复杂度: O(N 2 )
辅助空间: O(1)

方法2(使用堆栈)

  • 将第一个元素推入堆栈。
  • 一个一个地选择其余的元素,然后循环执行以下步骤。
    1. 将当前元素标记为next
    2. 如果 stack 不为空,则将 stack 的顶部元素与next进行比较。
    3. 如果 next 大于顶部元素,则从堆栈中弹出元素。 next是弹出元素的下一个更大的元素。
    4. 当弹出的元素小于next时,继续从堆栈中弹出。 next成为所有此类弹出元素的下一个更大元素。
  • 最后,压入栈中的下一个。
  • 步骤 2 中的循环结束后,从堆栈中弹出所有元素并打印 -1 作为它们的下一个元素。

下图是上述方法的试运行:

下面是上述方法的实现:

C

// A Stack based C program to find next 
//  greater element for all array elements.
#include 
#include 
#include 
#define STACKSIZE 100
  
// stack structure
struct stack {
    int top;
    int items[STACKSIZE];
};
  
// Stack Functions to be used by printNGE()
void push(struct stack* ps, int x)
{
    if (ps->top == STACKSIZE - 1) {
        printf("Error: stack overflown");
        getchar();
        exit(0);
    }
    else {
        ps->top += 1;
        int top = ps->top;
        ps->items[top] = x;
    }
}
  
bool isEmpty(struct stack* ps)
{
    return (ps->top == -1) ? true : false;
}
  
int pop(struct stack* ps)
{
    int temp;
    if (ps->top == -1) {
        printf("Error: stack underflow n");
        getchar();
        exit(0);
    }
    else {
        int top = ps->top;
        temp = ps->items[top];
        ps->top -= 1;
        return temp;
    }
}
  
/* prints element and NGE pair for all elements of
arr[] of size n */
void printNGE(int arr[], int n)
{
    int i = 0;
    struct stack s;
    s.top = -1;
    int element, next;
  
    /* push the first element to stack */
    push(&s, arr[0]);
  
    // iterate for rest of the elements
    for (i = 1; i < n; i++) {
        next = arr[i];
  
        if (isEmpty(&s) == false)
        {
            // if stack is not empty, then pop an element
            // from stack
            element = pop(&s);
  
            /* If the popped element is smaller than next,
               then a) print the pair b) keep popping while
               elements are smaller and stack is not empty
             */
            while (element < next) {
                printf("n %d --> %d", element, next);
                if (isEmpty(&s) == true)
                    break;
                element = pop(&s);
            }
  
            /* If element is greater than next, then push
               the element back */
            if (element > next)
                push(&s, element);
        }
  
        /* push next to stack so that we can find
           next greater for it */
        push(&s, next);
    }
  
    /* After iterating over the loop, the remaining
       elements in stack do not have the next greater
       element, so print -1 for them */
    while (isEmpty(&s) == false)
    {
        element = pop(&s);
        next = -1;
        printf("n %d --> %d", element, next);
    }
}
  
/* Driver code */
int main()
{
    int arr[] = { 11, 13, 21, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printNGE(arr, n);
    getchar();
    return 0;
}
输出
11 --> 13
13 --> 21
3 --> -1
21 --> -1

时间复杂度: O(N)
辅助空间: O(N)

最坏的情况发生在所有元素都按降序排序时。如果元素按降序排序,则每个元素最多处理 4 次。

  1. 最初推入堆栈。
  2. 处理下一个元素时从堆栈中弹出。
  3. 因为下一个元素更小,所以被推回堆栈。
  4. 在算法的第 3 步中从堆栈中弹出。

请参阅以相同顺序打印的优化解决方案。

有关详细信息,请参阅有关 Next Greater Element 的完整文章!