【LeetCode2834】美丽数组的最小和

【LeetCode2834】美丽数组的最小和

问题描述

给定两个正整数:n 和 target
如果数组 nums 满足下述条件,则称其为 美丽数组 。

1)nums.length == n.
2)nums 由两两互不相同的正整数组成。
3)在范围 [0, n-1] 内,不存在 两个 不同 下标 i 和 j ,使得 nums[i] + nums[j] == target 。
返回符合条件的美丽数组所可能具备的 最小 和,并对结果进行取模 10^9 +7。

举例

示例 1:
输入:n = 2, target = 3
输出:4
解释:nums = [1,3] 是美丽数组。

  • nums 的长度为 n = 2 。
  • nums 由两两互不相同的正整数组成。
  • 不存在两个不同下标 i 和 j ,使得 nums[i] + nums[j] == 3 。
    可以证明 4 是符合条件的美丽数组所可能具备的最小和。

示例 2:
输入:n = 3, target = 3
输出:8
解释:
nums = [1,3,4] 是美丽数组。

  • nums 的长度为 n = 3 。
  • nums 由两两互不相同的正整数组成。
  • 不存在两个不同下标 i 和 j ,使得 nums[i] + nums[j] == 3 。
    可以证明 8 是符合条件的美丽数组所可能具备的最小和。

示例 3:
输入:n = 1, target = 1
输出:1
解释:nums = [1] 是美丽数组。

思路挖掘

1)试想一个简单的问题,从[1, n]中取任意互不相等的数取n个,答案就是[1,n]这n个数,这是贪心算法的起源。
所以对于

条件2:nums 由两两互不相同的正整数组成;
满足这一条件,我们只需要运用贪心思想即可,即从1开始选择。

2)再设想一个问题,对于条件3,任意两个数相加不可以等于target.
假设任意两个数为a和b, 且a+b=target,则在选数的时候,如果选了a,则不能再选b.
推广:
对于target,选择1则放弃taeget-1,由于要确保和最小,所以我们从小数开始选。

假设target为奇数。例如target==7
则待选的结果如下:1,2,3,4,5,6,可选的结果为1,2,3
假设target为偶数。例如target==8
则待选的结果如下:1,2,3,4,5,6,7可选的结果为1,2,3,4

综上可知,对于target而言,可选的结果为1~target/2 整除

若target = 10 而 n = 3呢,那自然直接选1,2,3就行,所以当n小于target/2的值时,直接选n就行。
这里我们定义:
m = m i n ( n , ⌊ t a r g e t 2 ⌋ ) m=min(n,\lfloor\frac{target}{2}\rfloor) m=min(n,2target⌋)
即此时我们已经选出m个数,并且这m个数是连续的,对于连续的数,和为
s u m 1 = m ∗ ( m + 1 ) 2 sum_1 =\frac{m*(m+1)}{2} sum1=2m(m+1)
最后我们还需要满足条件1,即n个数,由于n一定是大于等于m的,故而我们还需要选择(n - m )个数
1 —— m —— t a r g e t —— n 1——m——target——n 1——m——target——n
我们知道,对于前m个数,我们是在1~target/2中进行选择的,由于要满足条件3,所以剩余的数我们只能从target开始选,一直选出(n-m)个连续的数即可。
则下一次选数的范围为:
[ t a r g e t , t a r g e t + n − m − 1 ] [target, target+n-m-1] [target,target+nm1]
则该(n-m)个数的和为:
s u m 2 = ( 2 ∗ t a r g e t + n − m + 1 ) 2 ∗ ( n − m ) sum_2 = \frac{(2*target+n-m+1)}{2}*(n-m) sum2=2(2target+nm+1)(nm)
综上,满足条件的美丽数组的最小和为:
m i n s u m = ( 2 ∗ t a r g e t + n − m + 1 ) ∗ ( n − m ) + m ∗ ( m + 1 ) 2 minsum=\frac{(2*target+n-m+1)*(n-m)+m*(m+1)}{2} minsum=2(2target+nm+1)(nm)+m(m+1)
其中
m = m i n ( n , ⌊ t a r g e t 2 ⌋ ) m=min(n,\lfloor\frac{target}{2}\rfloor) m=min(n,2target⌋)

代码展示

class Solution:
    def minimumPossibleSum(self, n: int, target: int) -> int:
        m = min(target // 2, n)
        ans = ((1 + m) * m //2 +(2 * target + n - m -1)*(n - m) //2) % (10**9 + 7)
        return ans
                           天天做题,天天好运
  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值