给你两个正整数:n 和 target 。
如果数组 nums 满足下述条件,则称其为 美丽数组 。
nums.length == n.nums由两两互不相同的正整数组成。- 在范围
[0, n-1]内,不存在 两个 不同 下标i和j,使得nums[i] + nums[j] == target。
返回符合条件的美丽数组所可能具备的 最小 和。
示例 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 <= 10^91 <= target <= 10^9
思路
有美丽数组定义知,1<= i < j < n 且 i + j === target 时,i 和 j 不能同时出现在美丽数组中,由于我们要求的是美丽数组的最小和,故 i 应该出现在数组中,而 j 不应该出现在数组中。我们可以从 i = 1 开始,
- 当
i < target时,j = target - i,比较i和j,当i<=j时,把i加入数组,当i > j时舍弃 - 当
i >= target时,把i加入数组 最后求数组和就是我们要求的解,代码如解法一。
本题我们还可以直接求解,设 half = target / 2,观察美丽数组,根据上面的分析知:
- 当
half >= n时,美丽数组是[1, 2, ..., n],求和为(n + 1) * n / 2 - 当
half < n时,设m = n - half,美丽数组是[1, 2, ..., half, target, target + 1, ..., target + m - 1],求和为(1 + half) * half / 2 + (target + target + m -1) * m / 2
上面问题就变成了求连续整数的和了,如解法二。
解题
解法一
/**
* @param {number} n
* @param {number} target
* @return {number}
*/
var minimumPossibleSum = function (n, target) {
const MOD = 10 ** 9 + 7;
let sum = 1;
let i = 2;
let k = 2;
while (i <= n) {
if (target <= k || target - k >= k) {
sum = (sum + k) % MOD;
i++;
}
k++;
}
return sum;
};
解法二
/**
* @param {number} n
* @param {number} target
* @return {number}
*/
var minimumPossibleSum = function (n, target) {
const MOD = 10 ** 9 + 7;
const half = Math.floor(target / 2);
if (half >= n) {
return (((n + 1) * n) / 2) % MOD;
} else {
const m = n - half;
return (
(((((half + 1) * half) / 2) % MOD) +
((((target + target + m - 1) * m) / 2) % MOD)) %
MOD
);
}
};