2834. 找出美丽数组的最小和
难度 : 中等
题目大意
给你两个正整数:
n
和target
。如果数组
nums
满足下述条件,则称其为 美丽数组 。
nums.length == n
.nums
由两两互不相同的正整数组成。- 在范围
[0, n-1]
内,不存在 两个 不同 下标i
和j
,使得nums[i] + nums[j] == target
。返回符合条件的美丽数组所可能具备的 最小 和,并对结果进行取模
10^9 + 7
。提示:
1 <= n <= 10^9
1 <= target <= 10^9
示例 1:
输入:n = 2, target = 3 输出:4 解释:nums = [1,3] 是美丽数组。 - nums 的长度为 n = 2 。 - nums 由两两互不相同的正整数组成。 - 不存在两个不同下标 i 和 j ,使得 nums[i] + nums[j] == 3 。 可以证明 4 是符合条件的美丽数组所可能具备的最小和。
分析
首先我们发现题目的数据范围很大,肯定是不能暴力解决,首先我们想一下怎么选才能让他们的和最小,首先肯定是从小到大进行选择, 如果选了一个数,那么根据题目的要求,在数组中不能存在nums[i] + nums[j] == target
,也就是说假设我们选的这个数字是x
,那么target - x
肯定要被剔除不能选,那么就有思路了,要总和最小,那么我们从小到大选,选完一个数就把对应的一个数字(存在的情况下)删除,那么怎么计算呢,前面就说了不能暴力枚举,但是我们简单的模拟一下就能发现其中的规律,我们最多选target / 2
个数字,并且我们选的这些数字是一段连续的正整数,我们可以使用等差数列求和的方式进行求解,(首项 + 末项) * 项数 / 2
但是还有一个问题
-
如果
n > target / 2
的时候,并且我们在1 ~ target - 1
中最多选target / 2
,那么我们就要在target ~ +inf
中选剩下的数字,选多少个呢,显然是n - target / 2
个,这一段也是连续的正整数,也就是说我们也可以用等差数列求和的方式进行计算 -
如果
n <= target / 2
,那么我们就只需要计算一段即可,也就是在1 ~ target - 1
中选最最前面的n
个数字,这样就全部解决了
注意别忘记取模
数学推理 + 贪心
class Solution {
public:
using LL = long long;
int minimumPossibleSum(int n, int target) {
int MOD = 1e9 + 7;
int cnt = n >= target / 2 ? target / 2 : n;
LL res = (1ll + cnt) * cnt / 2 % MOD;
if (n - cnt > 0) res = (res + (target * 2ll + n - cnt - 1) * (n - cnt) / 2) % MOD;
return res;
}
};
时间复杂度 : O ( 1 ) O(1) O(1)
结束了