2026-10-12:处理所有元素的成本。用go语言,给定一个整数序列 nums 和一个固定整数 k。你一开始拥有 k 点资源,需要按照从左到右的顺序逐个处理 nums 中的元素。处理某个元素时,会消耗等于该元素数值的资源。
如果在处理当前元素前,剩余资源不足以支付它的消耗,你可以进行一次补充:资源增加 k。第一次补充的代价是 1,第二次补充的代价是 2,之后每次补充的代价依次递增。也就是说,第 m 次补充需要花费 m。只要资源还不够,就可以继续补充,直到足以处理当前元素。
当前元素处理完成后,从资源中扣除 nums[i]。目标是在全部元素处理完毕后,让所有补充操作的总代价尽可能小。
如果最终的最小总代价很大,只需返回它对 1,000,000,007 取模后的结果。
1 <= nums.length <= 100000。
1 <= nums[i] <= 1000000000。
1 <= k <= 1000000000。
输入: nums = [1,2,3,4], k = 4。
输出: 3。
解释:
处理完 nums[0] 后,剩余资源为 4 - 1 = 3。
处理完 nums[1] 后,剩余资源为 3 - 2 = 1。
由于 nums[2] = 3,而当前只有 1 单位资源,因此执行第一次操作,成本为 1。处理完 nums[2] 后,剩余资源为 1 + 4 - 3 = 2。
由于 nums[3] = 4,而当前只有 2 单位资源,因此执行第二次操作,成本为 2。此时资源增加到 2 + 4 = 6,足以处理 nums[3]。
因此,总成本为 1 + 2 = 3。
题目来自力扣3987。
大体步骤如下:
第一步,统计所有元素的总消耗。
从左到右遍历整个 nums 数组,把每个元素的值累加起来,得到一个总和 total。这个总和表示处理完所有元素一共需要消耗多少资源。因为每个元素都必须被处理,所以无论处理顺序如何,总消耗量是固定的,就是数组所有元素之和。
第二步,计算最少需要补充多少次。
一开始拥有 k 点资源。每次补充都会让资源增加 k 点。假设一共补充了 m 次,那么总资源量就是初始的 k 加上补充增加的 m 乘以 k,也就是 (m + 1) 乘以 k。为了让所有元素都能被处理完,总资源量必须至少等于总消耗 total。因此需要满足:
(m + 1) * k >= total
变形后得到:
m >= total / k - 1
因为 m 必须是整数,所以最小的补充次数 m 是 ceil(total / k) - 1。这个值也可以用整数除法写成 (total - 1) // k。当 total 小于等于 k 时,这个结果为 0,表示不需要补充。代码中正是用 total 减 1 再除以 k 来得到补充次数。
第三步,计算补充操作的总代价。
如果一共补充了 m 次,那么代价分别是 1、2、3、……、m。总代价就是 1 到 m 的等差数列之和,公式为 m * (m + 1) / 2。这个和就是处理所有元素所需的最小总成本。因为补充次数 m 只取决于总消耗 total 和固定值 k,与具体在哪个元素处补充无关,所以这样直接计算是正确的。
第四步,对结果取模。
由于 total 和 m 可能非常大,最终总代价也会很大,题目要求返回对 1,000,000,007 取模后的结果。代码中先计算 m 并对 1,000,000,007 取模,得到 sum,然后计算 sum * (sum + 1) / 2 再对 1,000,000,007 取模。这样可以在保证结果正确的前提下避免数值过大。
以题目给出的例子说明:
nums = [1, 2, 3, 4],k = 4。
所有元素总和 total = 1 + 2 + 3 + 4 = 10。
补充次数 m = (10 - 1) // 4 = 9 // 4 = 2。
总代价 = 2 * (2 + 1) / 2 = 3。
所以输出为 3。
整个算法只遍历数组一次来计算总和,然后进行几次常数时间的算术运算和取模。因此总的时间复杂度是 O(n),其中 n 是数组 nums 的长度。额外空间复杂度是 O(1),因为只使用了几个固定数量的变量,没有开辟与输入规模相关的额外空间。
Go完整代码如下:
package main
import (
"fmt"
)
func minimumCost(nums []int, k int)int {
const mod = 1_000_000_007
total := 0
for _, x := range nums {
total += x
}
sum := (total - 1) / k % mod
return sum * (sum + 1) / 2 % mod
}func main() {
nums := []int{1, 2, 3, 4}
k := 4
result := minimumCost(nums, k)
fmt.Println(result)
}
Python完整代码如下:
# -*-coding:utf-8-*-
def minimumCost(nums, k):
MOD = 1_000_000_007
total = sum(nums)
s = (total - 1) // k % MOD
return s * (s + 1) // 2 % MODif __name__ == "__main__":
nums = [1, 2, 3, 4]
k = 4
result = minimumCost(nums, k)
print(result)
C++完整代码如下:
using namespace std;
const long long MOD = 1000000007LL;
int minimumCost(vector& nums, int k) {
long long total = 0;
for (int x : nums) {
total += x;
}
long long sum = (total - 1) / k % MOD;
return (int)(sum * (sum + 1) / 2 % MOD);
}int main() {
vector nums = {1, 2, 3, 4};
int k = 4;
int result = minimumCost(nums, k);
cout << result << endl;
return0;
}
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.