华为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,2,3,4,5
→ 输出:2,3,4,5,-1
- 输入:
2,5,2
→ 输出:5,-1,5
(需循环搜索)
Java
题目分析
我们需要在给定的环形数组中,为每个元素找到其后第一个更大的元素。环形数组意味着最后一个元素的下一个元素是第一个元素。例如,输入 2,5,2
中,第三个元素的下一个元素是第一个元素,但第一个更大的元素是第二个元素 5。
解决思路
单调栈算法:
- 遍历两次数组:模拟环形结构,每个元素会被处理两次。
- 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值是递减的。
- 处理每个元素:当当前元素比栈顶元素大时,栈顶元素的下一个更大元素即为当前元素,记录结果并出栈。
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();
}
}
代码解析
-
输入处理:
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]); }
- 读取输入字符串并分割为整数数组。
-
核心算法
nextGreaterElements
:int[] res = new int[n]; Arrays.fill(res, -1); Deque<Integer> stack = new ArrayDeque<>();
- 初始化结果数组
res
,默认值为 -1。 - 使用双端队列
Deque
作为栈,保存索引。
- 初始化结果数组
-
遍历两次数组:
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
,记录结果并出栈。 - 压入索引:仅在第一次遍历时压入索引,避免重复处理。
- 遍历逻辑:遍历
-
结果转换:
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。
综合分析
- 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为
4n
,仍为线性复杂度。 - 空间复杂度 O(n):栈和结果数组的空间均为
O(n)
。 - 正确性保证:
- 环形处理:通过遍历两次数组,确保每个元素能访问到环形后的元素。
- 单调栈特性:确保每个元素找到第一个更大元素。
- 适用场景:高效处理大规模数据(
n ≤ 10000
)。
python
题目分析
给定一个环形数组,每个元素需要找到其后的第一个更大元素。若不存在更大元素则输出 -1
。例如:
- 输入
2,5,2
的输出为5,-1,5
,最后一个元素循环到开头找到更大值。 - 输入
1,2,3,4,5
的输出为2,3,4,5,-1
。
解决思路
单调栈算法:
- 遍历两次数组:模拟环形结构,每个元素处理两次。
- 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值是递减的。
- 处理当前元素:若当前元素比栈顶元素大,则栈顶元素的下一个更大元素即为当前元素。
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)))
代码解析
-
初始化结果数组:
n = len(nums) res = [-1] * n
- 创建长度与输入相同的数组,默认值为
-1
。
- 创建长度与输入相同的数组,默认值为
-
遍历两次数组:
for i in range(2 * n): current_num = nums[i % n]
i % n
将索引映射到原数组范围,模拟环形结构。
-
维护单调递减栈:
while stack and current_num > nums[stack[-1]]: index = stack.pop() res[index] = current_num
- 当当前元素比栈顶元素大时,弹出栈顶并记录结果。
-
压入索引:
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
。
综合分析
- 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为
4n
,时间复杂度为线性。 - 空间复杂度 O(n):栈和结果数组的空间均为
O(n)
。 - 正确性保障:
- 环形处理:通过遍历两次数组,确保每个元素能访问到环形后的元素。
- 单调栈特性:栈中保存未找到更大元素的索引,保证找到的是第一个更大值。
- 适用场景:高效处理大规模数据(
n ≤ 10000
)。
JavaScript
题目分析
给定一个环形数组,每个元素需要找到其后第一个更大的元素。若不存在,则返回 -1
。例如:
- 输入
2,5,2
的输出为5,-1,5
,最后一个元素在循环中找到更大的5
。 - 输入
1,2,3,4,5
的输出为2,3,4,5,-1
。
解决思路
单调栈算法:
- 遍历两次数组:模拟环形结构,确保每个元素处理两次。
- 维护单调递减栈:栈中保存元素索引,栈顶元素对应的值最小。
- 处理当前元素:若当前元素比栈顶元素大,则栈顶元素的下一个更大元素为当前元素。
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
代码解析
-
初始化结果数组:
const result = new Array(n).fill(-1);
- 创建长度与输入数组相同的数组,默认值为
-1
。
- 创建长度与输入数组相同的数组,默认值为
-
遍历两次数组:
for (let i = 0; i < 2 * n; i++) { const currentNum = nums[i % n];
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); }
- 仅在第一次遍历时压入索引,避免重复处理。
示例测试
示例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
。
综合分析
- 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为
4n
,时间复杂度为线性。 - 空间复杂度 O(n):栈和结果数组的空间均为
O(n)
。 - 正确性保障:
- 环形处理:通过遍历两次数组,确保每个元素能访问到环形后的元素。
- 单调栈特性:栈中保存未找到更大元素的索引,保证找到的是第一个更大值。
- 适用场景:高效处理大规模数据(
n ≤ 10000
)。
C++
题目分析
给定一个环形数组,每个元素需要找到其后的第一个更大元素。若不存在,则返回 -1
。例如:
- 输入
1,2,3,4,5
的输出为2,3,4,5,-1
。 - 输入
2,5,2
的输出为5,-1,5
。
解决思路
单调栈算法:
- 遍历两次数组:通过取模操作模拟环形数组,确保每个元素的后继元素被检查两次。
- 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值最小。
- 更新结果数组:当当前元素大于栈顶元素时,栈顶元素的下一个更大元素即为当前元素。
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;
}
代码解析
-
结果数组初始化:
vector<int> res(n, -1);
- 创建一个长度为
n
的数组,所有元素初始化为-1
。
- 创建一个长度为
-
遍历两倍数组长度:
for (int i = 0; i < 2 * n; ++i) { int current = nums[i % n];
- 通过
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); }
- 仅在第一次遍历时压入索引,确保每个元素只处理一次。
示例测试
示例1:
输入:
1,2,3,4,5
输出:
2,3,4,5,-1
解析:
- 每个元素的后一个元素更大,最后一个元素无更大值。
示例2:
输入:
2,5,2
输出:
5,-1,5
解析:
- 第二个
2
循环到数组开头找到5
作为下一个更大元素。
综合分析
- 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为
4n
,时间复杂度为线性。 - 空间复杂度 O(n):栈和结果数组的空间均为
O(n)
。 - 正确性保障:
- 环形处理:通过遍历两次数组,确保每个元素的后继被完整检查。
- 单调栈特性:确保每个元素找到第一个更大的元素。
- 适用场景:高效处理大规模数据(
n ≤ 10000
)。
C语言
题目分析
给定一个环形数组,每个元素需要找到其后第一个更大的元素。若不存在,则返回 -1
。例如:
- 输入
2,5,2
的输出为5,-1,5
- 输入
1,2,3,4,5
的输出为2,3,4,5,-1
解决思路
单调栈算法:
- 遍历两次数组:通过取模操作模拟环形结构
- 维护单调递减栈:栈中保存元素索引,确保栈顶元素的值最小
- 更新结果数组:当当前元素大于栈顶元素时,更新结果
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
综合分析
- 时间复杂度 O(n):每个元素最多入栈和出栈两次
- 空间复杂度 O(n):栈和结果数组各占用线性空间
- 内存管理:
- 动态数组自动扩容
- 严格释放所有分配的内存
- 健壮性:
- 处理任意长度输入(最大 100,000 字符)
- 支持正负数输入
- 优势:
- 完全手动实现栈操作
- 更精细的内存控制
- 适合嵌入式等资源受限环境
GO
题目分析
给定一个环形数组,每个元素需要找到其后的第一个更大元素。若不存在则返回 -1
。例如:
- 输入
2,5,2
的输出为5,-1,5
,最后一个元素循环后找到更大的5
。 - 输入
1,2,3,4,5
的输出为2,3,4,5,-1
。
解决思路
单调栈算法:
- 遍历两次数组:通过取模操作模拟环形结构。
- 维护单调递减栈:栈中保存元素索引,确保栈顶元素对应的值最小。
- 更新结果数组:当当前元素大于栈顶元素时,栈顶元素的下一个更大元素即为当前元素。
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
}
代码解析
-
初始化结果数组:
res := make([]int, n) for i := range res { res[i] = -1 }
- 创建长度与输入相同的数组,默认值为
-1
。
- 创建长度与输入相同的数组,默认值为
-
模拟环形遍历:
for i := 0; i < 2*n; i++ { current := nums[i%n]
- 遍历
2n
次,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) }
- 只在第一次遍历时压入索引,避免重复处理。
示例测试
示例1:
输入:1,2,3,4,5
输出:2,3,4,5,-1
解析:
- 每个元素的后一个元素更大,最后一个元素无更大值。
示例2:
输入:2,5,2
输出:5,-1,5
解析:
- 第一个
2
的下一个更大元素是5
。 5
之后没有更大元素。- 最后一个
2
循环到开头找到5
。
综合分析
- 时间复杂度 O(n):每个元素最多入栈和出栈两次,总操作次数为
4n
,时间复杂度为线性。 - 空间复杂度 O(n):栈和结果数组的空间均为
O(n)
。 - 正确性保障:
- 环形处理:通过遍历两次数组,确保每个元素的后继被完整检查。
- 单调栈特性:栈中保存未找到更大元素的索引,确保找到的是第一个更大值。
- 适用场景:高效处理大规模数据(
n ≤ 10000
)。
更多内容:
https://www.kdocs.cn/l/cvk0eoGYucWA
本文发表于【纪元A梦】,关注我,获取更多实用教程/资源!