找出美丽数组的最小和

124 阅读2分钟

2834. 找出美丽数组的最小和 - 力扣(LeetCode)

给你两个正整数:ntarget

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

  • nums.length == n.
  • nums 由两两互不相同的正整数组成。
  • 在范围 [0, n-1] 内,不存在 两个 不同 下标 ij ,使得 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^9
  • 1 <= target <= 10^9

思路

有美丽数组定义知,1<= i < j < ni + j === target 时,ij 不能同时出现在美丽数组中,由于我们要求的是美丽数组的最小和,故 i 应该出现在数组中,而 j 不应该出现在数组中。我们可以从 i = 1 开始,

  • i < target 时,j = target - i,比较 ij,当 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
    );
  }
};