
2026-03-16:转换数组的最少操作次数。用go语言,给定两个整数数组:第一个长度为 n,第二个长度为 n+1。你可以对第一个数组反复施行三类操作中的任意一种——选择一个下标 i,使该位置的元素加 1、或减 1、或将该位置当前的值复制并追加到数组末尾。问:要把第一个数组变为第二个数组,至少需要多少次这样的操作?请返回最小操作次数。
1 <= n == nums1.length <= 100000。
nums2.length == n + 1。
1 <= nums1[i], nums2[i] <= 100000。
输入: nums1 = [2,8], nums2 = [1,7,3]。
输出: 4。
解释:
步骤 | i | 操作 | nums1[i] | 更新后的 nums1 |
|---|---|---|---|---|
1 | 0 | 追加 | - | [2, 8, 2] |
2 | 0 | 减少 | 减少到 1 | [1, 8, 2] |
3 | 1 | 减少 | 减少到 7 | [1, 7, 2] |
4 | 2 | 增加 | 增加到 3 | [1, 7, 3] |
因此,经过 4 次操作后,nums1 转换为 nums2。
题目来自力扣3724。
我们要把 nums1 从长度 n 变成 n+1,所以必须且只需要执行 1 次「追加操作」。 整个问题拆成 2 部分计算:
输入: nums1 = [2, 8] (n=2) nums2 = [1, 7, 3] (长度 3 = n+1) nums2 最后一个元素是 3(我们叫它 target)。
把 nums1 前 2 个元素,改成 nums2 前 2 个元素:
因为要把长度从 2 变 3,必须追加 1 次,这一步固定消耗: ✅ 追加操作数 = 1
目前累计:2 + 1 = 3 次。
追加的新元素,最终要变成 nums2 最后一个数:3。 我们可以选择从 nums1 任意一个位置复制值进行追加,不同选择成本不同:
我们遍历每一个位置,计算**「从该位置复制追加 → 改成 target=3」的最小成本**:
原 nums1[0] 最终会改成 1
原 nums1[1] 最终会改成 7
✅ 所有位置里,最小的修改成本是 2(选位置0追加)
基础加减(2) + 追加(1) + 最小修改成本(2) = 4 和题目输出完全一致!
当前元素 → 目标元素 需要加减多少次,全部累加。
这是把前 n 位对齐的固定成本。✅ 时间复杂度:O(n) (n 是 nums1 的长度)
✅ 额外空间复杂度:O(1) (常数级空间,不随输入规模变大)
package main
import (
"fmt"
"math"
)
func minOperations(nums1, nums2 []int)int64 {
target := nums2[len(nums2)-1]
ans := 1// 把元素追加到 nums1 的末尾需要一次操作
mn := math.MaxInt
for i, x := range nums1 {
y := nums2[i]
if x > y {
x, y = y, x // 保证 x <= y,简化后续逻辑
}
ans += y - x
// 如果 target 在 [x,y] 中,那么在从 x 变成 y 的过程中,可以顺带把 target 追加到 nums1 的末尾,代价为 0
// 如果 target < x,代价为 x-target
// 如果 target > y,代价为 target-y
mn = min(mn, max(x-target, target-y))
}
returnint64(ans + max(mn, 0)) // 如果 target 在 [x,y] 中,上面可能会算出负数
}
func main() {
nums1 := []int{2, 8}
nums2 := []int{1, 7, 3}
result := minOperations(nums1, nums2)
fmt.Println(result)
}

# -*-coding:utf-8-*-
import math
defminOperations(nums1, nums2):
target = nums2[len(nums2)-1]
ans = 1# 把元素追加到 nums1 的末尾需要一次操作
mn = math.inf
for i, x inenumerate(nums1):
y = nums2[i]
if x > y:
x, y = y, x # 保证 x <= y,简化后续逻辑
ans += y - x
# 如果 target 在 [x,y] 中,那么在从 x 变成 y 的过程中,可以顺带把 target 追加到 nums1 的末尾,代价为 0
# 如果 target < x,代价为 x-target
# 如果 target > y,代价为 target-y
mn = min(mn, max(x - target, target - y))
return ans + max(mn, 0) # 如果 target 在 [x,y] 中,上面可能会算出负数
# 测试
nums1 = [2, 8]
nums2 = [1, 7, 3]
result = minOperations(nums1, nums2)
print(result)
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
usingnamespace std;
long long minOperations(vector<int>& nums1, vector<int>& nums2) {
int target = nums2[nums2.size() - 1];
longlong ans = 1; // 把元素追加到 nums1 的末尾需要一次操作
int mn = INT_MAX;
for (int i = 0; i < nums1.size(); i++) {
int x = nums1[i];
int y = nums2[i];
if (x > y) {
swap(x, y); // 保证 x <= y,简化后续逻辑
}
ans += y - x;
// 如果 target 在 [x,y] 中,那么在从 x 变成 y 的过程中,可以顺带把 target 追加到 nums1 的末尾,代价为 0
// 如果 target < x,代价为 x-target
// 如果 target > y,代价为 target-y
mn = min(mn, max(x - target, target - y));
}
return ans + max(mn, 0); // 如果 target 在 [x,y] 中,上面可能会算出负数
}
int main() {
vector<int> nums1 = {2, 8};
vector<int> nums2 = {1, 7, 3};
longlong result = minOperations(nums1, nums2);
cout << result << endl;
return0;
}
·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。
·