🤖 AI总结
主题
计算数组最小稳定下标的算法问题
摘要
本文介绍求解最小稳定下标的方法,通过预处理后缀最小值和遍历前缀最大值,找到首个差值不超过k的下标,并提供多语言代码。
关键信息
- 1 使用后缀最小值数组和前缀最大值计算差值
- 2 找到第一个差值不超过k的下标
- 3 提供Go、Python、C++实现
2026-08-01:最小稳定下标Ⅰ。用go语言,给定一个长度为 n 的整数数组 nums 和一个整数 k。对于数组中的每个位置 i,先找出从数组开头到位置 i 这段区间内的最大值,再找出从位置 i 到数组末尾这段区间内的最小值,用前者减去后者,得到该位置的一个差值。如果这个差值不超过 k,就认为这个位置是符合条件的。现在需要在这些符合条件的位置中,找到下标最小的那一个;如果没有任何一个位置符合条件,则返回 -1。
1 <= nums.length <= 100。
0 <= nums[i] <= 1000000000。
0 <= k <= 1000000000。
输入: nums = [5,0,1,4], k = 3。
输出: 3。
解释:
在下标 0 处:[5] 中的最大值是 5,[5, 0, 1, 4] 中的最小值是 0,因此不稳定值为 5 – 0 = 5。
在下标 1 处:[5, 0] 中的最大值是 5,[0, 1, 4] 中的最小值是 0,因此不稳定值为 5 – 0 = 5。
在下标 2 处:[5, 0, 1] 中的最大值是 5,[1, 4] 中的最小值是 1,因此不稳定值为 5 – 1 = 4。
在下标 3 处:[5, 0, 1, 4] 中的最大值是 5,[4] 中的最小值是 4,因此不稳定值为 5 – 4 = 1。
这是第一个不稳定值小于等于 k = 3 的下标,因此答案是 3。
题目来自力扣3903。
根据给定的代码和题目要求,下面分步骤详细说明整个求解过程,最后给出时间和空间复杂度。
算法处理步骤
1.输入数据
给定一个整数数组nums(长度记为n,且n >= 1)和一个整数k。
2.预处理:计算后缀最小值数组
• 创建一个长度为n的数组sufMin,用于存储从每个位置i到数组末尾这段区间内的最小值。
• 首先将最后一个位置n-1的后缀最小值设为nums[n-1](因为区间只包含自身)。
• 然后从倒数第二个位置n-2开始,依次向前遍历:
对于每个i,比较nums[i]和已经计算出的sufMin[i+1],取其中的较小值赋给sufMin[i]。
这样,sufMin[i]就表示nums[i]到nums[n-1]这段范围内的最小值。
3.从左到右遍历并计算不稳定值
• 初始化一个变量preMax为 0(因为题目保证nums[i] >= 0,所以初始值 0 不会影响后续最大值更新;若nums[0]也为 0,则取最大值后仍为 0,若大于 0 则会被更新)。
• 按顺序遍历数组下标i从 0 到n-1:
• 更新preMax:将当前元素nums[i]与当前的preMax比较,取较大者作为新的preMax。此时preMax就代表了从数组开头到当前位置i这段区间内的最大值。
• 取出已经准备好的sufMin[i],它代表从当前位置i到数组末尾这段区间内的最小值。
• 计算不稳定值:差值 = preMax - sufMin[i]。
• 判断该差值是否小于等于k。
若是,则当前下标i就是第一个(也是最小的)符合条件的稳定下标,立即返回i。
4.结束遍历
如果遍历完整个数组都没有找到任何一个差值<= k的下标,则说明不存在稳定下标,返回-1。
示例推演(以nums = [5,0,1,4]k=3为例)
• 计算后缀最小值:
•sufMin[3] = 4
•sufMin[2] = min(1, 4) = 1
•sufMin[1] = min(0, 1) = 0
•sufMin[0] = min(5, 0) = 0
• 遍历过程:
•i=0:preMax = max(0,5)=5,差值 =5 - sufMin[0](0) = 5,>3,不满足。
•i=1:preMax = max(5,0)=5,差值 =5 - sufMin[1](0) = 5,>3,不满足。
•i=2:preMax = max(5,1)=5,差值 =5 - sufMin[2](1) = 4,>3,不满足。
•i=3:preMax = max(5,4)=5,差值 =5 - sufMin[3](4) = 1,≤3,满足,返回3。
复杂度分析
•时间复杂度:
预处理后缀最小值需要一次从右向左的遍历,时间复杂度为 O(n);
从左向右的遍历也需要一次,时间复杂度为 O(n)。
总时间复杂度为O(n)。
•额外空间复杂度:
主要开销是存储后缀最小值数组sufMin,长度为 n,占用 O(n) 空间;
其他变量(如preMax)均占用常数空间。
总额外空间复杂度为O(n)。
最终答案:当nums = [5,0,1,4],k=3时,返回3;复杂度为 O(n) 时间,O(n) 空间。
Go完整代码如下:
package main
import "fmt"
func firstStableIndex(nums []int, k int) int {
n := len(nums)
sufMin := make([]int, n) // 后缀最小值
sufMin[n-1] = nums[n-1]
for i := n - 2; i >= 0; i-- {
sufMin[i] = min(sufMin[i+1], nums[i])
}
preMax := 0 // 前缀最大值
for i, x := range nums {
preMax = max(preMax, x)
if preMax-sufMin[i] <= k {
return i
}
}
return -1
}func main() {
nums := []int{5, 0, 1, 4}
k := 3
result := firstStableIndex(nums, k)
fmt.Println(result)
}
![]()
Python完整代码如下:
# -*-coding:utf-8-*-
def first_stable_index(nums, k):
n = len(nums)
# 计算后缀最小值
suf_min = [0] * n
suf_min[-1] = nums[-1]
for i in range(n - 2, -1, -1):
suf_min[i] = min(suf_min[i + 1], nums[i])
pre_max = 0 # 注意:与原 Go 代码保持一致,初始化为 0
for i, x in enumerate(nums):
pre_max = max(pre_max, x)
if pre_max - suf_min[i] <= k:
return i
return -1if __name__ == "__main__":
nums = [5, 0, 1, 4]
k = 3
result = first_stable_index(nums, k)
print(result)
![]()
C++完整代码如下:
using namespace std;
int firstStableIndex(vector& nums, int k) {
int n = nums.size();
if (n == 0) return -1;
// 后缀最小值数组
vector sufMin(n);
sufMin[n - 1] = nums[n - 1];
for (int i = n - 2; i >= 0; --i) {
sufMin[i] = min(sufMin[i + 1], nums[i]);
}
int preMax = 0;
for (int i = 0; i < n; ++i) {
preMax = max(preMax, nums[i]);
if (preMax - sufMin[i] <= k) {
return i;
}
}
return -1;
}int main() {
vector nums = {5, 0, 1, 4};
int k = 3;
int result = firstStableIndex(nums, k);
cout << result << endl;
return 0;
}
![]()
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。