Skip to content

Commit

Permalink
✨feat: add 2656
Browse files Browse the repository at this point in the history
  • Loading branch information
SharingSource committed Nov 15, 2023
1 parent 2c4cf20 commit 0033019
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 0 deletions.
1 change: 1 addition & 0 deletions Index/数学.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
| [1775. 通过最少操作次数使数组的和相等](https://leetcode.cn/problems/equal-sum-arrays-with-minimum-number-of-operations/) | [LeetCode 题解链接](https://acoier.com/2022/12/09/1775.%20%E9%80%9A%E8%BF%87%E6%9C%80%E5%B0%91%E6%93%8D%E4%BD%9C%E6%AC%A1%E6%95%B0%E4%BD%BF%E6%95%B0%E7%BB%84%E7%9A%84%E5%92%8C%E7%9B%B8%E7%AD%89%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/) | 中等 | 🤩🤩🤩🤩 |
| [1780. 判断一个数字是否可以表示成三的幂的和](https://leetcode.cn/problems/check-if-number-is-a-sum-of-powers-of-three/) | [LeetCode 题解链接](https://acoier.com/2022/12/12/1780.%20%E5%88%A4%E6%96%AD%E4%B8%80%E4%B8%AA%E6%95%B0%E5%AD%97%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E8%A1%A8%E7%A4%BA%E6%88%90%E4%B8%89%E7%9A%84%E5%B9%82%E7%9A%84%E5%92%8C%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/) | 中等 | 🤩🤩🤩🤩🤩 |
| [1802. 有界数组中指定下标处的最大值](https://leetcode.cn/problems/maximum-value-at-a-given-index-in-a-bounded-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-value-at-a-given-index-in-a-bounded-array/solutions/2363016/gong-shui-san-xie-chang-gui-zong-he-ti-b-ohvx/) | 中等 | 🤩🤩🤩🤩 |
| [2656. K 个元素的最大和](https://leetcode.cn/problems/maximum-sum-with-exactly-k-elements/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-sum-with-exactly-k-elements/solutions/2527384/gong-shui-san-xie-deng-chai-shu-lie-qiu-b2g88/) | 简单 | 🤩🤩🤩 |
| [剑指 Offer 44. 数字序列中某一位的数字](https://leetcode.cn/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/) | [LeetCode 题解链接](https://leetcode.cn/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/solution/by-ac_oier-wgr8/) | 中等 | 🤩🤩🤩🤩 |
| [面试题 10.02. 变位词组](https://leetcode-cn.com/problems/group-anagrams-lcci/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/group-anagrams-lcci/solution/gong-shui-san-xie-tong-ji-bian-wei-ci-de-0iqe/) | 中等 | 🤩🤩🤩🤩 |
| [面试题 17.19. 消失的两个数字](https://leetcode.cn/problems/missing-two-lcci/) | [LeetCode 题解链接](https://leetcode.cn/problems/missing-two-lcci/solution/by-ac_oier-pgeh/) | 困难 | 🤩🤩🤩🤩 |
Expand Down
108 changes: 108 additions & 0 deletions LeetCode/2651-2660/2656. K 个元素的最大和(简单).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
### 题目描述

这是 LeetCode 上的 **[2656. K 个元素的最大和](https://leetcode.cn/problems/maximum-sum-with-exactly-k-elements/solutions/2527384/gong-shui-san-xie-deng-chai-shu-lie-qiu-b2g88/)** ,难度为 **简单**

Tag : 「数学」



给你一个下标从 `0` 开始的整数数组 `nums` 和一个整数 `k`

你需要执行以下操作恰好 `k` 次,最大化你的得分:

1.`nums` 中选择一个元素 `m`
2. 将选中的元素 `m` 从数组中删除。
3. 将新元素 `m + 1` 添加到数组中。
4. 你的得分增加 `m`

请你返回执行以上操作恰好 `k` 次后的最大得分。

示例 1:
```
输入:nums = [1,2,3,4,5], k = 3
输出:18
解释:我们需要从 nums 中恰好选择 3 个元素并最大化得分。
第一次选择 5 。和为 5 ,nums = [1,2,3,4,6] 。
第二次选择 6 。和为 6 ,nums = [1,2,3,4,7] 。
第三次选择 7 。和为 5 + 6 + 7 = 18 ,nums = [1,2,3,4,8] 。
所以我们返回 18 。
18 是可以得到的最大答案。
```
示例 2:
```
输入:nums = [5,5,5], k = 2
输出:11
解释:我们需要从 nums 中恰好选择 2 个元素并最大化得分。
第一次选择 5 。和为 5 ,nums = [5,5,6] 。
第二次选择 6 。和为 6 ,nums = [5,5,7] 。
所以我们返回 11 。
11 是可以得到的最大答案。
```

提示:
* $1 <= nums.length <= 100$
* $1 <= nums[i] <= 100$
* $1 <= k <= 100$

---

### 数学

为了使得分最高,每次应从 `nums` 中选最大值,选完后重放仍为最大值。

假设原始 `nums` 中的最大值为 `max`,那么问题转换为「等差数列」求和:首项为 `max`,末项为 `max + k - 1`,项数为 $k$,公差为 $1$。

Java 代码:
```Java
class Solution {
public int maximizeSum(int[] nums, int k) {
int max = 0;
for (int x : nums) max = Math.max(max, x);
return k * (max + max + k - 1) / 2;
}
}
```
C++ 代码:
```C++
class Solution {
public:
int maximizeSum(vector<int>& nums, int k) {
int maxv = 0;
for (auto x : nums) maxv = max(maxv, x);
return k * (maxv + maxv + k - 1) / 2;
}
};
```
Python 代码:
```Python
class Solution:
def maximizeSum(self, nums: List[int], k: int) -> int:
return k * (2 * max(nums) + k - 1) // 2
```
TypeScript 代码:
```TypeScript
function maximizeSum(nums: number[], k: number): number {
let max = 0;
for (const x of nums) max = Math.max(max, x);
return k * (max + max + k - 1) / 2;
};
```
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.2656` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

157 changes: 157 additions & 0 deletions LeetCode/2751-2760/2760. 最长奇偶子数组(简单).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
### 题目描述

这是 LeetCode 上的 **[2698. 求一个整数的惩罚数]()** ,难度为 **简单**

Tag : 「双指针」



给你一个下标从 $0$ 开始的整数数组 `nums` 和一个整数 `threshold`

请你从 `nums` 的子数组中找出以下标 `l` 开头、下标 `r` 结尾 ($0 <= l <= r < nums.length$) 且满足以下条件的 最长子数组 :

* `nums[l] % 2 == 0`
* 对于范围 $[l, r - 1]$ 内的所有下标 `i``nums[i] % 2 != nums[i + 1] % 2`
* 对于范围 $[l, r]$ 内的所有下标 `i``nums[i] <= threshold`

以整数形式返回满足题目要求的最长子数组的长度。

注意:子数组 是数组中的一个连续非空元素序列。

示例 1:
```
输入:nums = [3,2,5,4], threshold = 5
输出:3
解释:在这个示例中,我们选择从 l = 1 开始、到 r = 3 结束的子数组 => [2,5,4] ,满足上述条件。
因此,答案就是这个子数组的长度 3 。可以证明 3 是满足题目要求的最大长度。
```
示例 2:
```
输入:nums = [1,2], threshold = 2
输出:1
解释:
在这个示例中,我们选择从 l = 1 开始、到 r = 1 结束的子数组 => [2] 。
该子数组满足上述全部条件。可以证明 1 是满足题目要求的最大长度。
```
示例 3:
```
输入:nums = [2,3,4,5], threshold = 4
输出:3
解释:
在这个示例中,我们选择从 l = 0 开始、到 r = 2 结束的子数组 => [2,3,4] 。
该子数组满足上述全部条件。
因此,答案就是这个子数组的长度 3 。可以证明 3 是满足题目要求的最大长度。
```

提示:
* $1 <= nums.length <= 100$
* $1 <= nums[i] <= 100$
* $1 <= threshold <= 100$

---

### 双指针

整体题意:求 `nums` 中的最长的子数组 $[l, r]$,对于任意 $nums[i]$ 不超过 `threshold`,且从 $nums[l]$ 开始按照「先偶后奇」顺序交替。

容易想到「双指针」做法:

* 变量 `i` 作为当前子数组左端点,从前往后扫描 `nums`,首先确保 `i` 的合法性(跳过不满足 `nums[i] % 2 = 0``nums[i] <= threshold` 的位置);随后在固定左端点 `i` 前提下,找最远的右端点 `j`(值不超过 `threshold`,且奇偶性与前值交替)
* 得到当前连续段长度,更新 `ans`,从当前结束位置开始,重复上述过程,直到处理完 `nums`

Java 代码

```Java
class Solution {
public int longestAlternatingSubarray(int[] nums, int threshold) {
int n = nums.length, ans = 0, i = 0;
while (i < n) {
if ((nums[i] % 2 != 0 || nums[i] > threshold) && ++i >= 0) continue;
int j = i + 1, cur = nums[i] % 2;
while (j < n) {
if (nums[j] > threshold || nums[j] % 2 == cur) break;
cur = nums[j] % 2; j++;
}
ans = Math.max(ans, j - i);
i = j;
}
return ans;
}
}
```
C++ 代码
```C++
class Solution {
public:
int longestAlternatingSubarray(vector<int>& nums, int threshold) {
int n = nums.size(), ans = 0, i = 0;
while (i < n) {
if ((nums[i] % 2 != 0 || nums[i] > threshold) && ++i >= 0) continue;
int j = i + 1, cur = nums[i] % 2;
while (j < n) {
if (nums[j] > threshold || nums[j] % 2 == cur) break;
cur = nums[j] % 2; j++;
}
ans = max(ans, j - i);
i = j;
}
return ans;
}
};

```
Python 代码
```Python
class Solution:
def longestAlternatingSubarray(self, nums: List[int], threshold: int) -> int:
n, ans, i = len(nums), 0, 0
while i < n:
if nums[i] % 2 != 0 or nums[i] > threshold:
i += 1
continue
j, cur = i + 1, nums[i] % 2
while j < n:
if nums[j] > threshold or nums[j] % 2 == cur: break
cur, j = nums[j] % 2, j + 1
ans = max(ans, j - i)
i = j
return ans
```
TypeScript 代码
```TypeScript
function longestAlternatingSubarray(nums: number[], threshold: number): number {
let n = nums.length, ans = 0, i = 0
while (i < n) {
if ((nums[i] % 2 != 0 || nums[i] > threshold) && ++i >= 0) continue;
let j = i + 1, cur = nums[i] % 2;
while (j < n) {
if (nums[j] > threshold || nums[j] % 2 == cur) break;
cur = nums[j] % 2; j++;
}
ans = Math.max(ans, j - i);
i = j;
}
return ans;
};
```
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.2760` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

0 comments on commit 0033019

Please sign in to comment.