
2026-03-27:替换至多一个元素后最长非递减子数组。用go语言,给定一个整数数组 nums。
你最多只能选择其中一个位置的元素,把它改成任意整数(也可以选择不改)。
在允许这种“最多一次改动”的情况下,求能得到的最长连续非递减子数组的长度。
所谓“非递减子数组”,指的是该连续片段中任意相邻两项都满足:后一个元素 不小于 前一个元素。
子数组表示数组中一段连续的元素序列。
1 <= nums.length <= 100000。
-1000000000 <= nums[i] <= 1000000000。
输入: nums = [1,2,3,1,2]。
输出: 4。
解释:
将 nums[3] = 1 替换为 3 得到数组 [1, 2, 3, 3, 2]。
最长非递减子数组是 [1, 2, 3, 3],其长度为 4。
题目来自力扣3738。
我们的目标是:最多修改数组中1个元素(也可以不修改),找到数组中最长的连续非递减子数组(连续片段,相邻元素后≥前)。
示例:[1,2,3,1,2],修改第4个元素1为3,得到[1,2,3,3,2],最长子数组长度为4。
这道题用动态规划解决,核心是遍历数组时,记录两个关键状态,不额外存储全量数据,仅用变量更新:
遍历数组时,每一步都根据前一个元素和当前元素的大小关系,更新这两个状态,并同步记录全局最大值。
数组索引:0:1, 1:2, 2:3, 3:1, 4:2
初始状态:
pre0:保存上上个位置的f0值(初始0)f0:当前不修改的最长长度(初始1,第一个元素自身)f1:当前修改1次的最长长度(初始1)ans:最终答案(初始1)前一个元素是索引0(1),满足 1 ≤ 2(非递减):
f0:在前一个f0基础上+1 → 变为2;f1:在前一个f1基础上+1 → 变为2;f1;ans更新为2。前一个元素是索引1(2),满足 2 ≤ 3:
f0:+1 → 变为3;f1:+1 → 变为3;f1;ans更新为3。前一个元素是索引2(3),不满足 3 ≤ 1(递减):
f0:无法延续,重置为1(仅自身);f1:结合前两段有效长度,计算得到4;ans更新为4(这就是示例的答案)。前一个元素是索引3(1),满足 1 ≤ 2:
f0:+1 → 变为2;f1:延续之前的状态+1;ans保持4不变。遍历结束,全局最大值为4,与题目输出一致。
.
package main
import (
"fmt"
)
func longestSubarray(nums []int)int {
pre0, f0, f1 := 0, 1, 1
ans := 1// 以 nums[0] 结尾的子数组长度
for i := 1; i < len(nums); i++ {
tmp := f0
if nums[i-1] <= nums[i] {
f0++
f1++
} else {
f0 = 1
f1 = 0// 清除旧数据
}
if i >= 2 && nums[i-2] <= nums[i] {
f1 = max(f1, pre0+2)
} else {
f1 = max(f1, 2)
}
ans = max(ans, tmp+1, f1)
pre0 = tmp
}
return ans
}
func main() {
nums := []int{1, 2, 3, 1, 2}
result := longestSubarray(nums)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
def longestSubarray(nums):
if not nums:
return0
pre0, f0, f1 = 0, 1, 1
ans = 1 # 以 nums[0] 结尾的子数组长度
for i in range(1, len(nums)):
tmp = f0
if nums[i-1] <= nums[i]:
f0 += 1
f1 += 1
else:
f0 = 1
f1 = 0 # 清除旧数据
if i >= 2 and nums[i-2] <= nums[i]:
f1 = max(f1, pre0 + 2)
else:
f1 = max(f1, 2)
ans = max(ans, tmp + 1, f1)
pre0 = tmp
return ans
def main():
nums = [1, 2, 3, 1, 2]
result = longestSubarray(nums)
print(result)
if __name__ == "__main__":
main()
.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int longestSubarray(vector<int>& nums) {
if (nums.empty()) return0;
int pre0 = 0, f0 = 1, f1 = 1;
int ans = 1; // 以 nums[0] 结尾的子数组长度
for (int i = 1; i < nums.size(); i++) {
int tmp = f0;
if (nums[i-1] <= nums[i]) {
f0++;
f1++;
} else {
f0 = 1;
f1 = 0; // 清除旧数据
}
if (i >= 2 && nums[i-2] <= nums[i]) {
f1 = max(f1, pre0 + 2);
} else {
f1 = max(f1, 2);
}
ans = max({ans, tmp + 1, f1});
pre0 = tmp;
}
return ans;
}
int main() {
vector<int> nums = {1, 2, 3, 1, 2};
int result = longestSubarray(nums);
cout << result << endl;
return0;
}

·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。
·