[M数学] lc2829. k-avoiding 数组的最小总和(推公式+贪心模拟+好题)

1. 题目来源

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

前置题:

  • xxx

题单:

  • 待补充

2. 题目解析

2025年03月27日00:01:32

方法一:贪心模拟

  • 依据两数之和的思想,从 i=1 开始填,总共需要填 n 个数。
  • 如果当前的 i 不可用,那就一直 i++,找到一个可用的 i
  • 如果 k < i 就把 k-i 标记为不可用,因为此时 i 是被选中的数,对应的 k-i 就不可被选。
  • 累计答案即可。

这个贪心模拟的思路很不错哈,能够快速解决本题。一开始想的时候想到了二数之和,但没有考虑到这个写法。


方法二:数学解法

显然本题有数学解法,自己在考虑写的时候也是往这边在想,最终并没有推导的很完善吧,在一些边界情况下没有统一处理,还是分情况讨论的。当时的思路是

  • 通过双指针找到构成 k 的两个最近的数对,比如 7: {1,6},{2,5},{3,4} 那么就需要找到 {3,4} 这个数对。
  • 因为 4 及它后面的所有数 都要进行累加,这个累加的幅度就是 3。此时 4 应该从 7 开始,因为如果从 6 开始是没有意义的,{1,6} 仍然会等于 k。所以需要在最近的这个数对作为分界点,将后续的数字进行累加。就可以了。

这里有一些奇偶性的判断吧,比如

  • n = 5, K=6 就可以有 {1,5}, {2,4}, {3, 3}… 那么肯定就是 {1,2,3,6,7}, k//2 = 3
  • n=5,K=5 就可以有 {1,4}, {2,3},那么肯定就是 {1,2,5,6,7}, k // 2 = 2

这个分界点的位置就很关键,记为 m

  • m = min(k//2, n) k 的下取整。这里可能 k 很大,即便 k 除二后仍旧大于 n,那么 n 就是分界点。
  • 那么数组就被分成 1,2,3,…,m、k,k+1,k+2,…,k+n-m-1
  • 两段等差数列求和公式即可计算,(首项+尾项)*(项数)/ 2 即可。

  • 时间复杂度 O ( 1 ) O(1) O(1)
  • 空间复杂度 O ( 1 ) O(1) O(1) 返回值不计算

方法一:贪心模拟

func minimumSum(n int, k int) int {
    res := 0
    m := map[int]bool{}
    i := 1
    for n > 0 {
        for m[i] {
            i ++ 
        }

        if k > i {
            m[k - i] = true
        }
        res += i
        i ++
        n -- 
    }
    return res
}

方法二:数学公式

func minimumSum(n int, k int) int {
    m := min(k / 2, n)
    return (1 + m) * m / 2 + (k + k + n - m - 1) * (n - m) / 2
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值