diff --git a/solution/2100-2199/2195.Append K Integers With Minimal Sum/README.md b/solution/2100-2199/2195.Append K Integers With Minimal Sum/README.md index bd338c65a5450..5bfaf2061ce9f 100644 --- a/solution/2100-2199/2195.Append K Integers With Minimal Sum/README.md +++ b/solution/2100-2199/2195.Append K Integers With Minimal Sum/README.md @@ -44,47 +44,42 @@ nums 最终元素和为 5 + 6 + 1 + 2 + 3 + 4 + 7 + 8 = 36 ,这是所有情况 ### 方法一:排序 + 贪心 + 数学 +我们不妨向数组中加入两个哨兵节点,分别为 $0$ 和 $2 \times 10^9$。 + +然后我们对数组进行排序,那么对于数组中的任意两个相邻的元素 $a$ 和 $b$,区间 $[a+1, b-1]$ 中的整数都是未出现在数组中的,我们可以将这些整数加入到数组中。 + +因此,我们从小到大遍历数组中的相邻元素对 $(a, b)$,对于每个相邻元素对,我们计算区间 $[a+1, b-1]$ 中的整数个数 $m$,那么这 $m$ 个整数的和为 $\frac{m \times (a+1 + a+m)}{2}$,我们将这个和累加到答案中,并将 $k$ 减去 $m$。如果 $k$ 减到 $0$,我们就可以停止遍历了,返回答案。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组的长度。 + ```python class Solution: def minimalKSum(self, nums: List[int], k: int) -> int: - nums.append(0) - nums.append(2 * 10**9) + nums.extend([0, 2 * 10**9]) nums.sort() ans = 0 for a, b in pairwise(nums): - n = min(k, b - a - 1) - if n <= 0: - continue - k -= n - ans += (a + 1 + a + n) * n // 2 - if k == 0: - break + m = max(0, min(k, b - a - 1)) + ans += (a + 1 + a + m) * m // 2 + k -= m return ans ``` ```java class Solution { public long minimalKSum(int[] nums, int k) { - int[] arr = new int[nums.length + 2]; - arr[arr.length - 1] = (int) 2e9; - for (int i = 0; i < nums.length; ++i) { - arr[i + 1] = nums[i]; - } + int n = nums.length; + int[] arr = new int[n + 2]; + arr[1] = 2 * 1000000000; + System.arraycopy(nums, 0, arr, 2, n); Arrays.sort(arr); long ans = 0; - for (int i = 1; i < arr.length; ++i) { - int a = arr[i - 1], b = arr[i]; - int n = Math.min(k, b - a - 1); - if (n <= 0) { - continue; - } - k -= n; - ans += (long) (a + 1 + a + n) * n / 2; - if (k == 0) { - break; - } + for (int i = 0; i < n + 1 && k > 0; ++i) { + int m = Math.max(0, Math.min(k, arr[i + 1] - arr[i] - 1)); + ans += (arr[i] + 1L + arr[i] + m) * m / 2; + k -= m; } return ans; } @@ -99,13 +94,10 @@ public: nums.push_back(2e9); sort(nums.begin(), nums.end()); long long ans = 0; - for (int i = 1; i < nums.size(); ++i) { - int a = nums[i - 1], b = nums[i]; - int n = min(k, b - a - 1); - if (n <= 0) continue; - k -= n; - ans += 1ll * (a + 1 + a + n) * n / 2; - if (k == 0) break; + for (int i = 0; i < nums.size() - 1 && k > 0; ++i) { + int m = max(0, min(k, nums[i + 1] - nums[i] - 1)); + ans += 1LL * (nums[i] + 1 + nums[i] + m) * m / 2; + k -= m; } return ans; } @@ -113,23 +105,30 @@ public: ``` ```go -func minimalKSum(nums []int, k int) int64 { - nums = append(nums, 0, 2e9) +func minimalKSum(nums []int, k int) (ans int64) { + nums = append(nums, []int{0, 2e9}...) sort.Ints(nums) - ans := 0 - for i := 1; i < len(nums); i++ { - a, b := nums[i-1], nums[i] - n := min(k, b-a-1) - if n <= 0 { - continue - } - k -= n - ans += (a + 1 + a + n) * n / 2 - if k == 0 { - break - } + for i, b := range nums[1:] { + a := nums[i] + m := max(0, min(k, b-a-1)) + ans += int64(a+1+a+m) * int64(m) / 2 + k -= m } - return int64(ans) + return ans +} +``` + +```ts +function minimalKSum(nums: number[], k: number): number { + nums.push(...[0, 2 * 10 ** 9]); + nums.sort((a, b) => a - b); + let ans = 0; + for (let i = 0; i < nums.length - 1; ++i) { + const m = Math.max(0, Math.min(k, nums[i + 1] - nums[i] - 1)); + ans += Number((BigInt(nums[i] + 1 + nums[i] + m) * BigInt(m)) / BigInt(2)); + k -= m; + } + return ans; } ``` diff --git a/solution/2100-2199/2195.Append K Integers With Minimal Sum/README_EN.md b/solution/2100-2199/2195.Append K Integers With Minimal Sum/README_EN.md index 07efeb2e15fe7..618d4f02fc404 100644 --- a/solution/2100-2199/2195.Append K Integers With Minimal Sum/README_EN.md +++ b/solution/2100-2199/2195.Append K Integers With Minimal Sum/README_EN.md @@ -41,49 +41,44 @@ The sum of the six integers appended is 1 + 2 + 3 + 4 + 7 + 8 = 25, so we return ## Solutions -### Solution 1 +### Solution 1: Sorting + Greedy + Mathematics + +We can add two sentinel nodes to the array, which are $0$ and $2 \times 10^9$. + +Then we sort the array. For any two adjacent elements $a$ and $b$ in the array, the integers in the interval $[a+1, b-1]$ do not appear in the array, and we can add these integers to the array. + +Therefore, we traverse the adjacent element pairs $(a, b)$ in the array from small to large. For each adjacent element pair, we calculate the number of integers $m$ in the interval $[a+1, b-1]$. The sum of these $m$ integers is $\frac{m \times (a+1 + a+m)}{2}$. We add this sum to the answer and subtract $m$ from $k$. If $k$ is reduced to $0$, we can stop the traversal and return the answer. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Where $n$ is the length of the array. ```python class Solution: def minimalKSum(self, nums: List[int], k: int) -> int: - nums.append(0) - nums.append(2 * 10**9) + nums.extend([0, 2 * 10**9]) nums.sort() ans = 0 for a, b in pairwise(nums): - n = min(k, b - a - 1) - if n <= 0: - continue - k -= n - ans += (a + 1 + a + n) * n // 2 - if k == 0: - break + m = max(0, min(k, b - a - 1)) + ans += (a + 1 + a + m) * m // 2 + k -= m return ans ``` ```java class Solution { public long minimalKSum(int[] nums, int k) { - int[] arr = new int[nums.length + 2]; - arr[arr.length - 1] = (int) 2e9; - for (int i = 0; i < nums.length; ++i) { - arr[i + 1] = nums[i]; - } + int n = nums.length; + int[] arr = new int[n + 2]; + arr[1] = 2 * 1000000000; + System.arraycopy(nums, 0, arr, 2, n); Arrays.sort(arr); long ans = 0; - for (int i = 1; i < arr.length; ++i) { - int a = arr[i - 1], b = arr[i]; - int n = Math.min(k, b - a - 1); - if (n <= 0) { - continue; - } - k -= n; - ans += (long) (a + 1 + a + n) * n / 2; - if (k == 0) { - break; - } + for (int i = 0; i < n + 1 && k > 0; ++i) { + int m = Math.max(0, Math.min(k, arr[i + 1] - arr[i] - 1)); + ans += (arr[i] + 1L + arr[i] + m) * m / 2; + k -= m; } return ans; } @@ -98,13 +93,10 @@ public: nums.push_back(2e9); sort(nums.begin(), nums.end()); long long ans = 0; - for (int i = 1; i < nums.size(); ++i) { - int a = nums[i - 1], b = nums[i]; - int n = min(k, b - a - 1); - if (n <= 0) continue; - k -= n; - ans += 1ll * (a + 1 + a + n) * n / 2; - if (k == 0) break; + for (int i = 0; i < nums.size() - 1 && k > 0; ++i) { + int m = max(0, min(k, nums[i + 1] - nums[i] - 1)); + ans += 1LL * (nums[i] + 1 + nums[i] + m) * m / 2; + k -= m; } return ans; } @@ -112,23 +104,30 @@ public: ``` ```go -func minimalKSum(nums []int, k int) int64 { - nums = append(nums, 0, 2e9) +func minimalKSum(nums []int, k int) (ans int64) { + nums = append(nums, []int{0, 2e9}...) sort.Ints(nums) - ans := 0 - for i := 1; i < len(nums); i++ { - a, b := nums[i-1], nums[i] - n := min(k, b-a-1) - if n <= 0 { - continue - } - k -= n - ans += (a + 1 + a + n) * n / 2 - if k == 0 { - break - } + for i, b := range nums[1:] { + a := nums[i] + m := max(0, min(k, b-a-1)) + ans += int64(a+1+a+m) * int64(m) / 2 + k -= m } - return int64(ans) + return ans +} +``` + +```ts +function minimalKSum(nums: number[], k: number): number { + nums.push(...[0, 2 * 10 ** 9]); + nums.sort((a, b) => a - b); + let ans = 0; + for (let i = 0; i < nums.length - 1; ++i) { + const m = Math.max(0, Math.min(k, nums[i + 1] - nums[i] - 1)); + ans += Number((BigInt(nums[i] + 1 + nums[i] + m) * BigInt(m)) / BigInt(2)); + k -= m; + } + return ans; } ``` diff --git a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.cpp b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.cpp index 81636b0647b94..a5d92b4b2a4ce 100644 --- a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.cpp +++ b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.cpp @@ -5,13 +5,10 @@ class Solution { nums.push_back(2e9); sort(nums.begin(), nums.end()); long long ans = 0; - for (int i = 1; i < nums.size(); ++i) { - int a = nums[i - 1], b = nums[i]; - int n = min(k, b - a - 1); - if (n <= 0) continue; - k -= n; - ans += 1ll * (a + 1 + a + n) * n / 2; - if (k == 0) break; + for (int i = 0; i < nums.size() - 1 && k > 0; ++i) { + int m = max(0, min(k, nums[i + 1] - nums[i] - 1)); + ans += 1LL * (nums[i] + 1 + nums[i] + m) * m / 2; + k -= m; } return ans; } diff --git a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.go b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.go index d2c89321bdac4..b7fd7c7765a8f 100644 --- a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.go +++ b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.go @@ -1,18 +1,11 @@ -func minimalKSum(nums []int, k int) int64 { - nums = append(nums, 0, 2e9) +func minimalKSum(nums []int, k int) (ans int64) { + nums = append(nums, []int{0, 2e9}...) sort.Ints(nums) - ans := 0 - for i := 1; i < len(nums); i++ { - a, b := nums[i-1], nums[i] - n := min(k, b-a-1) - if n <= 0 { - continue - } - k -= n - ans += (a + 1 + a + n) * n / 2 - if k == 0 { - break - } + for i, b := range nums[1:] { + a := nums[i] + m := max(0, min(k, b-a-1)) + ans += int64(a+1+a+m) * int64(m) / 2 + k -= m } - return int64(ans) + return ans } \ No newline at end of file diff --git a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.java b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.java index c5c0b43787825..79f2adb07926c 100644 --- a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.java +++ b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.java @@ -1,23 +1,15 @@ class Solution { public long minimalKSum(int[] nums, int k) { - int[] arr = new int[nums.length + 2]; - arr[arr.length - 1] = (int) 2e9; - for (int i = 0; i < nums.length; ++i) { - arr[i + 1] = nums[i]; - } + int n = nums.length; + int[] arr = new int[n + 2]; + arr[1] = 2 * 1000000000; + System.arraycopy(nums, 0, arr, 2, n); Arrays.sort(arr); long ans = 0; - for (int i = 1; i < arr.length; ++i) { - int a = arr[i - 1], b = arr[i]; - int n = Math.min(k, b - a - 1); - if (n <= 0) { - continue; - } - k -= n; - ans += (long) (a + 1 + a + n) * n / 2; - if (k == 0) { - break; - } + for (int i = 0; i < n + 1 && k > 0; ++i) { + int m = Math.max(0, Math.min(k, arr[i + 1] - arr[i] - 1)); + ans += (arr[i] + 1L + arr[i] + m) * m / 2; + k -= m; } return ans; } diff --git a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.py b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.py index cdba5f2c342d6..4b97f49807ced 100644 --- a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.py +++ b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.py @@ -1,15 +1,10 @@ class Solution: def minimalKSum(self, nums: List[int], k: int) -> int: - nums.append(0) - nums.append(2 * 10**9) + nums.extend([0, 2 * 10**9]) nums.sort() ans = 0 for a, b in pairwise(nums): - n = min(k, b - a - 1) - if n <= 0: - continue - k -= n - ans += (a + 1 + a + n) * n // 2 - if k == 0: - break + m = max(0, min(k, b - a - 1)) + ans += (a + 1 + a + m) * m // 2 + k -= m return ans diff --git a/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.ts b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.ts new file mode 100644 index 0000000000000..8f30aef201376 --- /dev/null +++ b/solution/2100-2199/2195.Append K Integers With Minimal Sum/Solution.ts @@ -0,0 +1,11 @@ +function minimalKSum(nums: number[], k: number): number { + nums.push(...[0, 2 * 10 ** 9]); + nums.sort((a, b) => a - b); + let ans = 0; + for (let i = 0; i < nums.length - 1; ++i) { + const m = Math.max(0, Math.min(k, nums[i + 1] - nums[i] - 1)); + ans += Number((BigInt(nums[i] + 1 + nums[i] + m) * BigInt(m)) / BigInt(2)); + k -= m; + } + return ans; +}