返回

力扣503. 下一个更大元素 II-C语言实现-中等难度题

见解分享

下一个更大的元素指的是,以某个元素为基准,找到其右侧第一个比其大的元素。如果不存在比其大的元素,则返回-1。力扣503题为“下一个更大元素 II”,题目要求我们对循环数组进行操作。循环数组是指数组的末尾元素和首部元素相连,形成一个环形结构。

算法原理

该算法的核心思想是使用单调栈。单调栈是一种数据结构,其中元素按非递减顺序排列。当遍历数组时,我们将元素压入单调栈中。当遇到比栈顶元素更大的元素时,我们将栈顶元素弹出并将其下一个更大的元素设置为当前元素。如果当前元素小于或等于栈顶元素,我们将继续遍历数组。

C语言实现

#include <stdio.h>
#include <stdlib.h>

// 定义单调栈
struct Stack {
    int *arr;
    int top;
    int capacity;
};

// 创建单调栈
struct Stack* createStack(int capacity) {
    struct Stack *stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->arr = (int*)malloc(sizeof(int) * capacity);
    stack->top = -1;
    stack->capacity = capacity;
    return stack;
}

// 压入元素
void push(struct Stack *stack, int data) {
    if (stack->top == stack->capacity - 1) {
        printf("Stack is full!\n");
        return;
    }
    stack->arr[++stack->top] = data;
}

// 弹出元素
int pop(struct Stack *stack) {
    if (stack->top == -1) {
        printf("Stack is empty!\n");
        return -1;
    }
    return stack->arr[stack->top--];
}

// 获取栈顶元素
int peek(struct Stack *stack) {
    if (stack->top == -1) {
        printf("Stack is empty!\n");
        return -1;
    }
    return stack->arr[stack->top];
}

// 是否为空
int isEmpty(struct Stack *stack) {
    return stack->top == -1;
}

// 下一个更大元素 II
int* nextGreaterElements(int* nums, int numsSize, int* returnSize) {
    struct Stack *stack = createStack(numsSize);
    int *result = (int*)malloc(sizeof(int) * numsSize);

    // 遍历数组
    for (int i = 0; i < numsSize * 2; i++) {
        int index = i % numsSize;

        // 如果栈顶元素比当前元素小,则弹出栈顶元素并将其下一个更大的元素设置为当前元素
        while (!isEmpty(stack) && nums[peek(stack)] < nums[index]) {
            result[peek(stack)] = nums[index];
            pop(stack);
        }

        // 将当前元素压入栈中
        push(stack, index);
    }

    // 处理栈中剩余元素
    while (!isEmpty(stack)) {
        result[peek(stack)] = -1;
        pop(stack);
    }

    *returnSize = numsSize;
    return result;
}

// 主函数
int main() {
    // 初始化数组
    int nums[] = {1, 2, 1};
    int numsSize = sizeof(nums) / sizeof(nums[0]);

    // 计算下一个更大元素
    int returnSize = 0;
    int *result = nextGreaterElements(nums, numsSize, &returnSize);

    // 打印结果
    printf("下一个更大元素:");
    for (int i = 0; i < returnSize; i++) {
        printf(" %d", result[i]);
    }
    printf("\n");

    return 0;
}

复杂度分析

  • 时间复杂度:O(n),其中n是数组的长度。
  • 空间复杂度:O(n),因为我们使用了一个单调栈来存储元素。

示例

对于数组[1, 2, 1],算法的输出结果为[2, -1, 2]。

总结

力扣503题“下一个更大元素 II”考察了我们使用单调栈解决问题的能力。通过本教程,您应该对该算法有了更深入的了解,并能够轻松地将其应用到其他类似的问题中。