LeetCode 2834.找出美丽数组的最小和:数学(等差数列求和)——O(1)的做法

【LetMeFly】2834.找出美丽数组的最小和:数学(等差数列求和)------O(1)的做法

力扣题目链接:https://leetcode.cn/problems/find-the-minimum-possible-sum-of-a-beautiful-array/

给你两个正整数:ntarget

如果数组 nums 满足下述条件,则称其为 美丽数组

  • nums.length == n.
  • nums 由两两互不相同的正整数组成。
  • 在范围 [0, n-1] 内,不存在 两个 不同 下标 ij ,使得 nums[i] + nums[j] == target

返回符合条件的美丽数组所可能具备的 最小 和,并对结果进行取模 109 + 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 <= n <= 109
  • 1 <= target <= 109

方法一:数学(等差数列求和)------O(1)的做法

n n n个不同的正整数,任意两数之和不为 t a r g e t target target,问这些数的最小和为多少。

怎么构造这个数组?当然是每个元素越小越好。那就从 0 , 1 , 2 , ⋯ 0,1,2,\cdots 0,1,2,⋯开始呗。

这样最多能到几?最多能到 ⌊ t a r g e t 2 ⌋ \lfloor\frac{target}2\rfloor ⌊2target⌋。
原理(可跳过)

在 ≤ t a r g e t \le target ≤target的数当中,存在 a a a则不能存在 t a r g e t − a target-a target−a。

例如 t a r g e t = 5 target=5 target=5时, 1 1 1和 4 4 4不能同时存在。选哪个?もちろん选 4 4 4。

如果这些数不够 n n n个咋办?那就从 t a r g e t target target开始依次往上选就好了。 t a r g e t , t a r g e t + 1 , t a r g e t + 2 , ⋯ target, target + 1, target + 2, \cdots target,target+1,target+2,⋯,直到选够为止。

又有等差数列 a , a + 1 , a + 2 , ⋯   , b a, a + 1, a + 2, \cdots, b a,a+1,a+2,⋯,b的和为 ( a + b ) × ( b − a + 1 ) 2 \frac{(a + b)\times(b - a + 1)}2 2(a+b)×(b−a+1),因此可以在 O ( 1 ) O(1) O(1)的时空复杂度内得出结果。

  • 时间复杂度 O ( N 2 ) O(N^2) O(N2)
  • 空间复杂度 O ( N log ⁡ N ) O(N\log N) O(NlogN)

AC代码

C++
cpp 复制代码
const int MOD = 1e9 + 7;
class Solution {  // AC,14.77%,62.50%
private:
    inline long long cal(long long l, long long r) {
        return (l + r) * (r - l + 1) / 2;
    }
public:
    int minimumPossibleSum(int n, int target) {
        long long half = target / 2;
        if (n <= half) {
            return cal(1, n);
        }
        return (cal(1, half) + cal(target, target + n - half - 1)) % MOD;
    }
};
Python
python 复制代码
MOD = int(1e9) + 7
class Solution:
    def cal(self, l: int, r: int) -> int:
        return (l + r) * (r - l + 1) // 2

    def minimumPossibleSum(self, n: int, target: int) -> int:
        half = target >> 1
        if n <= half:
            return self.cal(1, n)
        return (self.cal(1, half) + self.cal(target, target + n - half - 1)) % MOD

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/136565723

相关推荐
王老师青少年编程9 小时前
2026年6月GESP真题及题解(C++一级):交税
c++·题解·真题·gesp·一级·2026年6月·交税
金銀銅鐵10 小时前
费马小定理
python·数学·算法
旖-旎17 小时前
《LeetCode 746 使用最小花费爬楼梯 || LeetCode 91 解码方法》
c++·算法·leetcode·动态规划
wabs66618 小时前
关于动态规划【力扣1035.不相交的线和53.最大子数组和的思考】
算法·leetcode·动态规划
退休倒计时18 小时前
【每日一题】LeetCode 199. 二叉树的右视图 TypeScript
算法·leetcode·typescript
王老师青少年编程18 小时前
2026年6月GESP真题及题解(C++二级):完全平方数计数
c++·题解·真题·gesp·二级·2026年6月·完全平方数计数
硕风和炜19 小时前
【LeetCode: 1301. 最大得分的路径数目 + DP】
java·算法·leetcode·动态规划·dp·记忆化搜索
剑挑星河月20 小时前
94.二叉树的中序遍历
java·算法·leetcode
Sw1zzle20 小时前
算法入门(三):二分查找 - 基础模板 & 边界控制(Leetcode 704/35/278/34/69/367)
算法·leetcode
剑挑星河月1 天前
234. 回文链表
java·数据结构·算法·leetcode·链表