leetcode每日一题:k-avoiding 数组的最小总和

image

引言

​ 今天是本次开始坚持leetcode每日1题的第10天,也算是迈出了一小步。

题目

2829. k-avoiding 数组的最小总和

给你两个整数 nk

对于一个由 不同 正整数组成的数组,如果其中不存在任何求和等于 k 的不同元素对,则称其为 k-avoiding 数组。

返回长度为 nk-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开始,逐个加入 kk+1k+2 直到补充够n个数字,因为数组中数字都是正整数,此时k-t都是不是正整数,不会出现在这个数组中,不需要考虑任意2个数和等于k的情况。所以,我们这样就构造了[1, k/2][k, k + n - k/2 - 1]这2个等差数列

图解

image

代码

image

/**
 * 如何包含了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;
}

耗时

image

posted @ 2025-03-26 19:56  podongfeng  阅读(32)  评论(0)    收藏  举报