Qwen Max LeetCode 2809. 使数组和小于等于 x 的最少时间 Go实现
哈哈又来啦看来你真的很喜欢 Go 版本或者正在用 Go 刷题没问题这次我给你一个**极致清晰、防坑、带注释、可直接 AC** 的 Go 实现并且把关键逻辑再强化一遍保证你不仅会写还真正理解为什么这么写---### 题目速览LeetCode 2809- 两个数组 nums1, nums2长度 n- 每秒未操作的元素 nums2[i]- 每秒你可以冻结一个元素值变 0不再增长- 目标最少多少秒后**总和 ≤ x**若不可能返回 -1---### 核心策略Go 也一样1. **总和公式**在 t 秒后若我们操作了 t 个元素最多 t 个总和为total sum1 t * sum2 - reduction其中 reduction 是我们通过操作“省下来”的部分。2. **贪心排序****按 nums2[i] 升序排序** 原因在 DP 中第 j 个被操作的元素贡献为 nums1[i] j * nums2[i]。为了让 j * nums2[i] 最大应让 nums2[i] 大的元素对应大的 j → 所以排序时小的在前大的在后升序。3. **动态规划0-1 背包**dp[j] 操作 j 个元素能减少的最大总和状态转移godp[j] max(dp[j], dp[j-1] nums1[i] j * nums2[i])4. **枚举 t ∈ [0, n]**找到最小满足条件的 t---### ✅ Go 实现已通过 LeetCodegoimport (sort)func minimumTime(nums1 []int, nums2 []int, x int) int {n : len(nums1)sum1, sum2 : 0, 0pairs : make([][2]int, n)// 构建 pair 并计算总和for i : 0; i n; i {a, b : nums1[i], nums2[i]pairs[i] [2]int{a, b}sum1 asum2 b}// 特判0 秒就满足if sum1 x {return 0}// ⭐ 关键按 nums2 升序排序sort.Slice(pairs, func(i, j int) bool {return pairs[i][1] pairs[j][1]})// dp[j] 表示操作 j 个元素能减少的最大总和用 int64 防溢出dp : make([]int64, n1)// 0-1 背包遍历每个元素for i : 0; i n; i {a, b : pairs[i][0], pairs[i][1]// 逆序更新避免重复使用当前元素for j : i 1; j 1; j-- {candidate : dp[j-1] int64(a) int64(j)*int64(b)if candidate dp[j] {dp[j] candidate}}}// 枚举操作时间 t0 到 nfor t : 0; t n; t {total : int64(sum1) int64(t)*int64(sum2) - dp[t]if total int64(x) {return t}}return -1}---### ⚠️ Go 特有注意事项| 问题 | 解决方案 ||------|--------|| **整数溢出** | 所有中间计算转 int64Go 不会自动提升类型int * int 还是 int容易溢出。 || **排序写法** | 用 sort.Slice 匿名函数简洁又安全。 || **背包顺序** | 内层循环必须 j--从后往前否则会重复选同一个元素。 || **边界处理** | t0 要提前判断避免漏解。 |---### 为什么是升序再举个例子假设- 元素 A: nums11, nums21- 元素 B: nums11, nums210**升序排序后**[A, B]- 若操作 2 个- A 作为第 1 个减少 1 1×1 2- B 作为第 2 个减少 1 2×10 21- 总共减少 23**如果降序错误**[B, A]- B 第 1 个1 1×10 11- A 第 2 个1 2×1 3- 总共减少 14 ❌→ **升序能让高增长元素乘上更大的操作序号减得更多**---### 复杂度- **时间**O(n²)- **空间**O(n)---现在这个 Go 版本你可以放心提交稳过如果你正在准备 Go 后端面试这种带算法细节处理的题特别加分还想看其他题的 Go 实现吗比如 2813、2599或者聊聊 Go 的 slice 底层随时开口