当前位置: 首页 > news >正文

华为OD机试真题——阿里巴巴找黄金宝箱 IV(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

在这里插入图片描述

2025 A卷 200分 题型

本文涵盖详细解题思路、代码注释、讲解、复杂的分析以及测试用例;
并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式!

华为OD机试真题《阿里巴巴找黄金宝箱 IV》:


目录

    • 题目名称:阿里巴巴找黄金宝箱 IV
      • 题目描述
    • Java
      • 题目分析
      • 解决思路
      • Java 代码实现
      • 代码解析
      • 示例测试
        • 示例1:
        • 示例2:
      • 综合分析
    • python
      • 题目分析
      • 解决思路
      • Python 代码实现
      • 代码解析
      • 示例测试
        • 示例1:
        • 示例2:
      • 综合分析
    • JavaScript
      • 题目分析
      • 解决思路
      • JavaScript 代码实现
      • 代码解析
      • 示例测试
        • 示例1:
        • 示例2:
      • 综合分析
    • C++
      • 题目分析
      • 解决思路
      • C++ 代码实现
      • 代码解析
      • 示例测试
        • 示例1:
        • 示例2:
      • 综合分析
    • C语言
      • 题目分析
      • 解决思路
      • C 代码实现
      • 代码解析
        • 1. 栈结构定义
        • 2. 栈操作函数
        • 3. 核心算法
        • 4. 输入处理
      • 示例测试
        • 示例1:
        • 示例2:
      • 综合分析
    • GO
      • 题目分析
      • 解决思路
      • Go 代码实现
      • 代码解析
      • 示例测试
        • 示例1:
        • 示例2:
      • 综合分析
    • 更多内容:


题目名称:阿里巴巴找黄金宝箱 IV


知识点: 字符串、栈操作(单调栈算法)、逻辑处理
时间限制: 1秒
空间限制: 256MB
限定语言: 不限


题目描述

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地。藏宝地有编号从0-N的箱子排列成环(编号最大的箱子的下一个是编号为0的箱子),每个箱子贴有一个数字。请输出每个箱子之后的第一个比它大的数字,若不存在则输出-1。

输入描述
输入一个数字子串,数字之间用逗号分隔,例如:1,2,3,1

  • 1 ≤ 子串中数字个数 ≤ 10000
  • -100000 ≤ 每个数字值 ≤ 100000

输出描述
结果以逗号分隔,例如:2,3,6,-1,6

测试用例

  1. 输入:1,2,3,4,5 → 输出:2,3,4,5,-1
  2. 输入:2,5,2 → 输出:5,-1,5(需循环搜索)

Java

题目分析

我们需要在给定的环形数组中,为每个元素找到其后第一个更大的元素。环形数组意味着最后一个元素的下一个元素是第一个元素。例如,输入 2,5,2 中,第三个元素的下一个元素是第一个元素,但第一个更大的元素是第二个元素 5。


解决思路

单调栈算法

  1. 遍历两次数组:模拟环形结构,每个元素会被处理两次。
  2. 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值是递减的。
  3. 处理每个元素:当当前元素比栈顶元素大时,栈顶元素的下一个更大元素即为当前元素,记录结果并出栈。

Java 代码实现

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        String[] parts = input.split(",");
        int[] nums = new int[parts.length];
        for (int i = 0; i < parts.length; i++) {
            nums[i] = Integer.parseInt(parts[i]);
        }

        int[] result = nextGreaterElements(nums);
        System.out.println(arrayToString(result));
    }

    private static int[] nextGreaterElements(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];
        Arrays.fill(res, -1);
        Deque<Integer> stack = new ArrayDeque<>();

        // 遍历两次数组,模拟环形结构
        for (int i = 0; i < 2 * n; i++) {
            int num = nums[i % n];
            // 维护单调递减栈,处理栈顶元素
            while (!stack.isEmpty() && num > nums[stack.peek()]) {
                int index = stack.pop();
                res[index] = num;
            }
            // 只在第一次遍历时压入索引
            if (i < n) {
                stack.push(i);
            }
        }
        return res;
    }

    private static String arrayToString(int[] arr) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            if (i > 0) {
                sb.append(",");
            }
            sb.append(arr[i]);
        }
        return sb.toString();
    }
}

代码解析

  1. 输入处理

    String input = scanner.nextLine();
    String[] parts = input.split(",");
    int[] nums = new int[parts.length];
    for (int i = 0; i < parts.length; i++) {
        nums[i] = Integer.parseInt(parts[i]);
    }
    
    • 读取输入字符串并分割为整数数组。
  2. 核心算法 nextGreaterElements

    int[] res = new int[n];
    Arrays.fill(res, -1);
    Deque<Integer> stack = new ArrayDeque<>();
    
    • 初始化结果数组 res,默认值为 -1。
    • 使用双端队列 Deque 作为栈,保存索引。
  3. 遍历两次数组

    for (int i = 0; i < 2 * n; i++) {
        int num = nums[i % n];
        while (!stack.isEmpty() && num > nums[stack.peek()]) {
            int index = stack.pop();
            res[index] = num;
        }
        if (i < n) {
            stack.push(i);
        }
    }
    
    • 遍历逻辑:遍历 2n 次,i % n 模拟环形访问。
    • 维护栈:栈中保存未找到更大元素的索引,确保栈中元素对应的值是递减的。
    • 处理栈顶元素:当当前元素 num 大于栈顶元素对应的值时,栈顶元素的下一个更大元素即为 num,记录结果并出栈。
    • 压入索引:仅在第一次遍历时压入索引,避免重复处理。
  4. 结果转换

    private static String arrayToString(int[] arr) {
        // 将数组转换为逗号分隔的字符串
    }
    
    • 将结果数组转换为题目要求的输出格式。

示例测试

示例1:

输入

1,2,3,4,5

输出

2,3,4,5,-1

解析

  • 每个元素的下一个更大元素依次为后一个元素,最后一个元素无更大值。
示例2:

输入

2,5,2

输出

5,-1,5

解析

  • 第一个 2 的下一个更大元素是 5。
  • 5 之后没有更大元素。
  • 最后一个 2 的下一个更大元素是循环后的 5。

综合分析

  1. 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为 4n,仍为线性复杂度。
  2. 空间复杂度 O(n):栈和结果数组的空间均为 O(n)
  3. 正确性保证
    • 环形处理:通过遍历两次数组,确保每个元素能访问到环形后的元素。
    • 单调栈特性:确保每个元素找到第一个更大元素。
  4. 适用场景:高效处理大规模数据(n ≤ 10000)。

python

题目分析

给定一个环形数组,每个元素需要找到其后的第一个更大元素。若不存在更大元素则输出 -1。例如:

  • 输入 2,5,2 的输出为 5,-1,5,最后一个元素循环到开头找到更大值。
  • 输入 1,2,3,4,5 的输出为 2,3,4,5,-1

解决思路

单调栈算法

  1. 遍历两次数组:模拟环形结构,每个元素处理两次。
  2. 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值是递减的。
  3. 处理当前元素:若当前元素比栈顶元素大,则栈顶元素的下一个更大元素即为当前元素。

Python 代码实现

def next_greater_elements(nums):
    n = len(nums)
    res = [-1] * n  # 初始化结果数组,默认-1
    stack = []  # 单调递减栈,保存索引

    # 遍历两倍数组长度,模拟环形结构
    for i in range(2 * n):
        current_num = nums[i % n]  # 当前元素(环形取模)

        # 维护单调栈:当前元素比栈顶元素大时,更新结果
        while stack and current_num > nums[stack[-1]]:
            index = stack.pop()  # 弹出栈顶索引
            res[index] = current_num  # 记录下一个更大元素

        # 只在第一次遍历时压入索引,避免重复处理
        if i < n:
            stack.append(i % n)

    return res

# 输入处理与结果输出
input_str = input().strip()
nums = list(map(int, input_str.split(',')))
result = next_greater_elements(nums)
print(','.join(map(str, result)))

代码解析

  1. 初始化结果数组

    n = len(nums)
    res = [-1] * n
    
    • 创建长度与输入相同的数组,默认值为 -1
  2. 遍历两次数组

    for i in range(2 * n):
        current_num = nums[i % n]
    
    • i % n 将索引映射到原数组范围,模拟环形结构。
  3. 维护单调递减栈

    while stack and current_num > nums[stack[-1]]:
        index = stack.pop()
        res[index] = current_num
    
    • 当当前元素比栈顶元素大时,弹出栈顶并记录结果。
  4. 压入索引

    if i < n:
        stack.append(i % n)
    
    • 仅在第一次遍历时压入索引,避免重复处理。

示例测试

示例1:

输入

1,2,3,4,5

输出

2,3,4,5,-1

解析

  • 每个元素的下一个更大元素是后一个元素,最后一个元素无更大值。
示例2:

输入

2,5,2

输出

5,-1,5

解析

  • 第一个 2 的下一个更大元素是 5
  • 5 之后没有更大元素。
  • 最后一个 2 循环到开头找到 5

综合分析

  1. 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为 4n,时间复杂度为线性。
  2. 空间复杂度 O(n):栈和结果数组的空间均为 O(n)
  3. 正确性保障
    • 环形处理:通过遍历两次数组,确保每个元素能访问到环形后的元素。
    • 单调栈特性:栈中保存未找到更大元素的索引,保证找到的是第一个更大值。
  4. 适用场景:高效处理大规模数据(n ≤ 10000)。

JavaScript

题目分析

给定一个环形数组,每个元素需要找到其后第一个更大的元素。若不存在,则返回 -1。例如:

  • 输入 2,5,2 的输出为 5,-1,5,最后一个元素在循环中找到更大的 5
  • 输入 1,2,3,4,5 的输出为 2,3,4,5,-1

解决思路

单调栈算法

  1. 遍历两次数组:模拟环形结构,确保每个元素处理两次。
  2. 维护单调递减栈:栈中保存元素索引,栈顶元素对应的值最小。
  3. 处理当前元素:若当前元素比栈顶元素大,则栈顶元素的下一个更大元素为当前元素。

JavaScript 代码实现

function nextGreaterElements(nums) {
    const n = nums.length;
    const result = new Array(n).fill(-1); // 初始化结果数组为-1
    const stack = []; // 单调栈,保存索引
    
    // 遍历两倍数组长度以模拟环形结构
    for (let i = 0; i < 2 * n; i++) {
        const currentNum = nums[i % n]; // 当前元素(环形取模)
        
        // 维护栈:当前元素比栈顶元素大时,更新结果
        while (stack.length > 0 && currentNum > nums[stack[stack.length - 1]]) {
            const index = stack.pop();
            result[index] = currentNum; // 栈顶元素的下一个更大元素是当前元素
        }
        
        // 仅在第一次遍历时压入索引,避免重复处理
        if (i < n) {
            stack.push(i % n);
        }
    }
    
    return result;
}

// 输入处理与结果输出
const input = '2,5,2'; // 示例输入
const nums = input.split(',').map(Number);
const result = nextGreaterElements(nums);
console.log(result.join(',')); // 输出:5,-1,5

代码解析

  1. 初始化结果数组

    const result = new Array(n).fill(-1);
    
    • 创建长度与输入数组相同的数组,默认值为 -1
  2. 遍历两次数组

    for (let i = 0; i < 2 * n; i++) {
        const currentNum = nums[i % n];
    
    • i % n 将索引映射到原数组范围,模拟环形结构。
  3. 维护单调递减栈

    while (stack.length > 0 && currentNum > nums[stack[stack.length - 1]]) {
        const index = stack.pop();
        result[index] = currentNum;
    }
    
    • 当当前元素比栈顶元素大时,弹出栈顶并记录结果。
  4. 压入索引

    if (i < n) {
        stack.push(i % n);
    }
    
    • 仅在第一次遍历时压入索引,避免重复处理。

示例测试

示例1:

输入

const input = '1,2,3,4,5';

输出

2,3,4,5,-1

解析

  • 每个元素的下一个更大元素是后一个元素,最后一个元素无更大值。
示例2:

输入

const input = '2,5,2';

输出

5,-1,5

解析

  • 第一个 2 的下一个更大元素是 5
  • 5 之后没有更大元素。
  • 最后一个 2 循环到开头找到 5

综合分析

  1. 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为 4n,时间复杂度为线性。
  2. 空间复杂度 O(n):栈和结果数组的空间均为 O(n)
  3. 正确性保障
    • 环形处理:通过遍历两次数组,确保每个元素能访问到环形后的元素。
    • 单调栈特性:栈中保存未找到更大元素的索引,保证找到的是第一个更大值。
  4. 适用场景:高效处理大规模数据(n ≤ 10000)。

C++

题目分析

给定一个环形数组,每个元素需要找到其后的第一个更大元素。若不存在,则返回 -1。例如:

  • 输入 1,2,3,4,5 的输出为 2,3,4,5,-1
  • 输入 2,5,2 的输出为 5,-1,5

解决思路

单调栈算法

  1. 遍历两次数组:通过取模操作模拟环形数组,确保每个元素的后继元素被检查两次。
  2. 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值最小。
  3. 更新结果数组:当当前元素大于栈顶元素时,栈顶元素的下一个更大元素即为当前元素。

C++ 代码实现

#include <iostream>
#include <vector>
#include <stack>
#include <sstream>
#include <string>

using namespace std;

vector<int> nextGreaterElements(vector<int>& nums) {
    int n = nums.size();
    vector<int> res(n, -1);  // 初始化结果数组为-1
    stack<int> st;           // 单调栈,保存未找到更大元素的索引

    // 遍历两倍数组长度以模拟环形结构
    for (int i = 0; i < 2 * n; ++i) {
        int current = nums[i % n];  // 当前元素(环形取模)

        // 维护单调栈:当前元素比栈顶元素大时,更新结果
        while (!st.empty() && current > nums[st.top()]) {
            int idx = st.top();
            st.pop();
            res[idx] = current;  // 记录栈顶索引对应的下一个更大元素
        }

        // 仅在第一次遍历时压入索引,避免重复处理
        if (i < n) {
            st.push(i % n);
        }
    }
    return res;
}

int main() {
    string input;
    getline(cin, input);  // 读取输入字符串

    // 解析输入为整数数组
    vector<int> nums;
    stringstream ss(input);
    string token;
    while (getline(ss, token, ',')) {
        nums.push_back(stoi(token));
    }

    // 计算下一个更大元素数组
    vector<int> res = nextGreaterElements(nums);

    // 输出结果
    for (int i = 0; i < res.size(); ++i) {
        if (i != 0) {
            cout << ",";
        }
        cout << res[i];
    }
    cout << endl;

    return 0;
}

代码解析

  1. 结果数组初始化

    vector<int> res(n, -1);
    
    • 创建一个长度为 n 的数组,所有元素初始化为 -1
  2. 遍历两倍数组长度

    for (int i = 0; i < 2 * n; ++i) {
        int current = nums[i % n];
    
    • 通过 i % n 模拟环形数组,遍历两次原数组。
  3. 维护单调栈

    while (!st.empty() && current > nums[st.top()]) {
        int idx = st.top();
        st.pop();
        res[idx] = current;
    }
    
    • 当前元素比栈顶元素大时,弹出栈顶并更新结果。
  4. 压入索引

    if (i < n) {
        st.push(i % n);
    }
    
    • 仅在第一次遍历时压入索引,确保每个元素只处理一次。

示例测试

示例1:

输入

1,2,3,4,5

输出

2,3,4,5,-1

解析

  • 每个元素的后一个元素更大,最后一个元素无更大值。
示例2:

输入

2,5,2

输出

5,-1,5

解析

  • 第二个 2 循环到数组开头找到 5 作为下一个更大元素。

综合分析

  1. 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为 4n,时间复杂度为线性。
  2. 空间复杂度 O(n):栈和结果数组的空间均为 O(n)
  3. 正确性保障
    • 环形处理:通过遍历两次数组,确保每个元素的后继被完整检查。
    • 单调栈特性:确保每个元素找到第一个更大的元素。
  4. 适用场景:高效处理大规模数据(n ≤ 10000)。

C语言

题目分析

给定一个环形数组,每个元素需要找到其后第一个更大的元素。若不存在,则返回 -1。例如:

  • 输入 2,5,2 的输出为 5,-1,5
  • 输入 1,2,3,4,5 的输出为 2,3,4,5,-1

解决思路

单调栈算法

  1. 遍历两次数组:通过取模操作模拟环形结构
  2. 维护单调递减栈:栈中保存元素索引,确保栈顶元素的值最小
  3. 更新结果数组:当当前元素大于栈顶元素时,更新结果

C 代码实现

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

#define INIT_CAPACITY 100  // 栈初始容量

// 定义栈结构
typedef struct {
    int *data;     // 存储索引的数组
    int top;       // 栈顶指针
    int capacity;  // 栈容量
} Stack;

// 初始化栈
void initStack(Stack *s) {
    s->data = (int*)malloc(INIT_CAPACITY * sizeof(int));
    s->top = -1;
    s->capacity = INIT_CAPACITY;
}

// 扩展栈容量
void resizeStack(Stack *s) {
    s->capacity *= 2;
    s->data = (int*)realloc(s->data, s->capacity * sizeof(int));
}

// 压栈操作
void push(Stack *s, int val) {
    if (s->top == s->capacity - 1) resizeStack(s);
    s->data[++s->top] = val;
}

// 弹栈操作
int pop(Stack *s) {
    return s->data[s->top--];
}

// 获取栈顶元素
int top(Stack *s) {
    return s->data[s->top];
}

// 判断栈是否为空
int isEmpty(Stack *s) {
    return s->top == -1;
}

// 释放栈内存
void freeStack(Stack *s) {
    free(s->data);
}

// 核心算法函数
int* nextGreaterElements(int* nums, int numsSize, int* returnSize) {
    int* res = (int*)malloc(numsSize * sizeof(int));
    *returnSize = numsSize;
    memset(res, -1, numsSize * sizeof(int));  // 初始化结果数组
    
    Stack s;
    initStack(&s);
    
    // 遍历两倍数组长度模拟环形
    for (int i = 0; i < 2 * numsSize; i++) {
        int current = nums[i % numsSize];
        
        // 维护单调栈
        while (!isEmpty(&s) && current > nums[top(&s)]) {
            int idx = pop(&s);
            res[idx] = current;
        }
        
        // 只压入第一次遍历的索引
        if (i < numsSize) {
            push(&s, i % numsSize);
        }
    }
    
    freeStack(&s);
    return res;
}

// 字符串分割函数
int* parseInput(const char* input, int* size) {
    char* str = strdup(input);
    int count = 0;
    char* token = strtok(str, ",");
    int* arr = NULL;
    
    while (token) {
        arr = (int*)realloc(arr, (count + 1) * sizeof(int));
        arr[count++] = atoi(token);
        token = strtok(NULL, ",");
    }
    
    *size = count;
    free(str);
    return arr;
}

int main() {
    char input[100000];
    fgets(input, sizeof(input), stdin);
    input[strcspn(input, "\n")] = '\0';  // 去除换行符
    
    int numsSize;
    int* nums = parseInput(input, &numsSize);
    
    int returnSize;
    int* res = nextGreaterElements(nums, numsSize, &returnSize);
    
    // 输出结果
    for (int i = 0; i < returnSize; i++) {
        if (i > 0) printf(",");
        printf("%d", res[i]);
    }
    
    free(nums);
    free(res);
    return 0;
}

代码解析

1. 栈结构定义
typedef struct {
    int *data;     // 存储索引的数组
    int top;       // 栈顶指针
    int capacity;  // 栈容量
} Stack;
  • 使用动态数组实现栈,支持自动扩容
2. 栈操作函数
void push(Stack *s, int val) {
    if (s->top == s->capacity - 1) resizeStack(s);
    s->data[++s->top] = val;
}
  • 压栈时自动检查容量,不足时自动扩容
3. 核心算法
int* nextGreaterElements(int* nums, int numsSize, int* returnSize) {
    int* res = (int*)malloc(numsSize * sizeof(int));
    memset(res, -1, numsSize * sizeof(int));
    
    Stack s;
    initStack(&s);
    
    for (int i = 0; i < 2 * numsSize; i++) {
        int current = nums[i % numsSize];
        while (!isEmpty(&s) && current > nums[top(&s)]) {
            int idx = pop(&s);
            res[idx] = current;
        }
        if (i < numsSize) push(&s, i % numsSize);
    }
    
    freeStack(&s);
    return res;
}
  • 关键逻辑
    • 遍历 2*n 次模拟环形
    • 维护单调递减栈
    • 只在第一次遍历时压入索引
4. 输入处理
int* parseInput(const char* input, int* size) {
    char* str = strdup(input);
    int count = 0;
    int* arr = NULL;
    // 使用 strtok 分割字符串
}
  • 动态解析逗号分隔的输入字符串

示例测试

示例1:

输入:

1,2,3,4,5

输出:

2,3,4,5,-1

解析过程:

  • 每个元素的后继即为其下一个更大值
  • 最后一个元素没有更大值
示例2:

输入:

2,5,2

输出:

5,-1,5

解析过程:

  • 第一个 2 找到后面的 5
  • 第二个 5 没有更大值
  • 第三个 2 循环找到开头的 5

综合分析

  1. 时间复杂度 O(n):每个元素最多入栈和出栈两次
  2. 空间复杂度 O(n):栈和结果数组各占用线性空间
  3. 内存管理
    • 动态数组自动扩容
    • 严格释放所有分配的内存
  4. 健壮性
    • 处理任意长度输入(最大 100,000 字符)
    • 支持正负数输入
  5. 优势
    • 完全手动实现栈操作
    • 更精细的内存控制
    • 适合嵌入式等资源受限环境

GO

题目分析

给定一个环形数组,每个元素需要找到其后的第一个更大元素。若不存在则返回 -1。例如:

  • 输入 2,5,2 的输出为 5,-1,5,最后一个元素循环后找到更大的 5
  • 输入 1,2,3,4,5 的输出为 2,3,4,5,-1

解决思路

单调栈算法

  1. 遍历两次数组:通过取模操作模拟环形结构。
  2. 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值最小。
  3. 更新结果数组:当当前元素大于栈顶元素时,栈顶元素的下一个更大元素即为当前元素。

Go 代码实现

package main

import (
	"fmt"
	"strings"
)

func nextGreaterElements(nums []int) []int {
	n := len(nums)
	res := make([]int, n)
	for i := range res {
		res[i] = -1 // 初始化结果数组为-1
	}
	stack := []int{} // 单调栈,保存索引

	// 遍历两倍数组长度以模拟环形结构
	for i := 0; i < 2*n; i++ {
		current := nums[i%n] // 当前元素(环形取模)

		// 维护单调栈:当前元素比栈顶元素大时,更新结果
		for len(stack) > 0 && current > nums[stack[len(stack)-1]] {
			top := stack[len(stack)-1]
			stack = stack[:len(stack)-1] // 弹出栈顶
			res[top] = current          // 记录下一个更大元素
		}

		// 仅在第一次遍历时压入索引
		if i < n {
			stack = append(stack, i%n)
		}
	}

	return res
}

func main() {
	// 示例测试
	input1 := "1,2,3,4,5"
	nums1 := parseInput(input1)
	result1 := nextGreaterElements(nums1)
	fmt.Println("示例1输出:", strings.Join(strings.Fields(fmt.Sprint(result1)), ",")) // 输出: 2,3,4,5,-1

	input2 := "2,5,2"
	nums2 := parseInput(input2)
	result2 := nextGreaterElements(nums2)
	fmt.Println("示例2输出:", strings.Join(strings.Fields(fmt.Sprint(result2)), ",")) // 输出: 5,-1,5
}

// 将输入字符串转换为整数数组
func parseInput(input string) []int {
	strs := strings.Split(input, ",")
	nums := make([]int, len(strs))
	for i, s := range strs {
		fmt.Sscanf(s, "%d", &nums[i])
	}
	return nums
}

代码解析

  1. 初始化结果数组

    res := make([]int, n)
    for i := range res {
        res[i] = -1
    }
    
    • 创建长度与输入相同的数组,默认值为 -1
  2. 模拟环形遍历

    for i := 0; i < 2*n; i++ {
        current := nums[i%n]
    
    • 遍历 2n 次,i%n 将索引映射到原数组范围。
  3. 维护单调栈

    for len(stack) > 0 && current > nums[stack[len(stack)-1]] {
        top := stack[len(stack)-1]
        stack = stack[:len(stack)-1]
        res[top] = current
    }
    
    • 当当前元素大于栈顶元素时,弹出栈顶并更新结果。
  4. 压入索引

    if i < n {
        stack = append(stack, i%n)
    }
    
    • 只在第一次遍历时压入索引,避免重复处理。

示例测试

示例1:

输入1,2,3,4,5
输出2,3,4,5,-1
解析

  • 每个元素的后一个元素更大,最后一个元素无更大值。
示例2:

输入2,5,2
输出5,-1,5
解析

  • 第一个 2 的下一个更大元素是 5
  • 5 之后没有更大元素。
  • 最后一个 2 循环到开头找到 5

综合分析

  1. 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为 4n,时间复杂度为线性。
  2. 空间复杂度 O(n):栈和结果数组的空间均为 O(n)
  3. 正确性保障
    • 环形处理:通过遍历两次数组,确保每个元素的后继被完整检查。
    • 单调栈特性:栈中保存未找到更大元素的索引,确保找到的是第一个更大值。
  4. 适用场景:高效处理大规模数据(n ≤ 10000)。

更多内容:

https://www.kdocs.cn/l/cvk0eoGYucWA

本文发表于【纪元A梦】,关注我,获取更多实用教程/资源!

相关文章:

  • 子串-滑动窗口的最大值
  • 科研软件分享
  • AI agents系列之全从零开始构建
  • 批处理(Batch Processing)的详解、流程及框架/工具的详细对比
  • 前端工程化之自动化构建
  • .NET MCP 文档
  • 多模态思维链(Multimodal Chain of Thought, MCoT)六大技术支柱在医疗领域的应用
  • OpenCv--换脸
  • 群辉搭建静态网站
  • 基于 Qt 的 BMP 图像数据存取至 SQLite 数据库的实现
  • WSL2 配置和离线安装linux系统。
  • 基础算法篇(5)(蓝桥杯常考点)—动态规划(C/C++)
  • PyCharm 开发工具 修改字体大小及使用滚轮没有反应
  • 【Wasserstein-1 距离】
  • Spring Boot + ShardingSphere 分库分表实战:电商订单场景案例
  • cline 提示词工程指南-架构篇
  • 美团即时零售大动作,将独立的闪购将会改变什么?
  • UE5 设置父物体和解除父子关系(移除子物体)
  • 磁珠详解:特性参数、选型方法、厂商对比及与电感的区别
  • 【动手学强化学习】番外6-MAPPO应用框架学习
  • 早睡1小时,变化有多惊人?第一个就没想到
  • 价格周报|猪价继续回暖:二次育肥热度仍存,对猪价仍有一定支撑
  • 驻美国使馆发言人就美方希就关税问题与中方对话答记者问
  • 苏炳添任暨南大学体育学院院长
  • 民生访谈|公共数据如何既开放又安全?政务领域如何适度运用人工智能?
  • 央行25日开展6000亿元MLF操作,期限为1年期