引言
今天是本次开始坚持leetcode每日1题的第10天,也算是迈出了一小步。
题目
2829. k-avoiding 数组的最小总和
给你两个整数 n
和 k
。
对于一个由 不同 正整数组成的数组,如果其中不存在任何求和等于 k 的不同元素对,则称其为 k-avoiding 数组。
返回长度为 n
的 k-avoiding 数组的可能的最小总和。
示例 1:
输入:n = 5, k = 4 输出:18 解释:设若 k-avoiding 数组为 [1,2,4,5,6] ,其元素总和为 18 。 可以证明不存在总和小于 18 的 k-avoiding 数组。
示例 2:
输入:n = 2, k = 6 输出:3 解释:可以构造数组 [1,2] ,其元素总和为 3 。 可以证明不存在总和小于 3 的 k-avoiding 数组。
提示:
-
1 <= n, k <= 50
思路
还是先读懂题目,要求不存在任何求和等于 k 的不同元素对,所以,如何我们在数组中选择了数字t
,就不能包含k-t
。贪心的,我们让数组中线包含1、2、3这样较小的数,但是不包含k-t
。这样,在数组中,我们最多能有k/2个数。这时会产生2种情况:
-
n <= k/2
,此时我们只要构造[1, n]
这样一个包含n个数字的数组即可,直接使用高斯求和就可以 -
n > k/2
,此时,我们构造了[1, k/2]
这个数组后,还不足n个,我们还需要补充n-k/2
个数字,我们可以从k开始,逐个加入k
,k+1
,k+2
直到补充够n个数字,因为数组中数字都是正整数,此时k-t
都是不是正整数,不会出现在这个数组中,不需要考虑任意2个数和等于k的情况。所以,我们这样就构造了[1, k/2]
和[k, k + n - k/2 - 1]
这2个等差数列
图解
代码
/*** 如何包含了t,那么就不能包含k-t,所以这2个数中应该尽量取小的那个* 如果从 1 到 k/2 的数组,还是数量不足n,那么就要从k开始加入,依次加入 k, k+1, k+2... 直到凑满n个数*/ public int minimumSum(int n, int k) {if (n <= k / 2) {return (1 + n) * n / 2;}// 先计算 [1, k/2] 数组的和 再计算 [k, k + n - k/2 - 1]的和return (1 + k / 2) * (k / 2) / 2 + (k + k + n - k/2 - 1) * (n - k / 2) / 2; }