Skip to content

Commit 47a8815

Browse files
committed
✨feat: Add 1005
1 parent 2d30934 commit 47a8815

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed

Index/堆.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
| [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-atoms/solution/gong-shui-san-xie-shi-yong-xiao-ji-qiao-l5ak4/) | 困难 | 🤩🤩🤩🤩 |
1515
| [786. 第 K 个最小的素数分数](https://leetcode-cn.com/problems/k-th-smallest-prime-fraction/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/k-th-smallest-prime-fraction/solution/gong-shui-san-xie-yi-ti-shuang-jie-you-x-8ymk/) | 中等 | 🤩🤩🤩 |
1616
| [987. 二叉树的垂序遍历](https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree/solution/gong-shui-san-xie-yi-ti-shuang-jie-dfs-h-wfm3/) | 困难 | 🤩🤩🤩🤩🤩 |
17+
| [1005. K 次取反后最大化的数组和](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/solution/gong-shui-san-xie-jian-dan-fen-qing-kuan-6qwu/) | 简单 | 🤩🤩🤩🤩 |
1718
| [1337. 矩阵中战斗力最弱的 K 行](https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix/solution/gong-shui-san-xie-yi-ti-shuang-jie-po-su-7okx/) | 简单 | 🤩🤩🤩 |
1819
| [1834. 单线程 CPU](https://leetcode-cn.com/problems/single-threaded-cpu/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/single-threaded-cpu/solution/gong-shui-san-xie-shu-ju-jie-gou-yun-yon-1qk0/) | 中等 | 🤩🤩🤩🤩 |
1920
| [面试题 17.14. 最小K个数](https://leetcode-cn.com/problems/smallest-k-lcci/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/smallest-k-lcci/solution/gong-shui-san-xie-yi-ti-si-jie-you-xian-yy5k5/) | 中等 | 🤩🤩🤩🤩 |

Index/模拟.md

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
| [859. 亲密字符串](https://leetcode-cn.com/problems/buddy-strings/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/buddy-strings/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-q056/) | 简单 | 🤩🤩🤩🤩🤩 |
6363
| [867. 转置矩阵](https://leetcode-cn.com/problems/transpose-matrix/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/transpose-matrix/solution/yi-you-wei-jin-huo-xu-ni-neng-kan-kan-zh-m53m/) | 简单 | 🤩🤩🤩🤩 |
6464
| [896. 单调数列](https://leetcode-cn.com/problems/monotonic-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/monotonic-array/solution/wei-shi-yao-yi-ci-bian-li-yao-bi-liang-c-uglp/) | 简单 | 🤩🤩🤩🤩 |
65+
| [1005. K 次取反后最大化的数组和](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/solution/gong-shui-san-xie-jian-dan-fen-qing-kuan-6qwu/) | 简单 | 🤩🤩🤩🤩 |
6566
| [1047. 删除字符串中的所有相邻重复项](https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string/solution/cong-30-dao-100wu-chong-shi-xian-jie-jue-vkah/) | 简单 | 🤩🤩🤩🤩 |
6667
| [1104. 二叉树寻路](https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree/solution/gong-shui-san-xie-yi-ti-shuang-jie-mo-ni-rw2d/) | 中等 | 🤩🤩🤩 |
6768
| [1436. 旅行终点站](https://leetcode-cn.com/problems/destination-city/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/destination-city/solution/gong-shui-san-xie-jian-dan-fang-jia-mo-n-y47c/) | 简单 | 🤩🤩🤩🤩🤩 |

Index/贪心算法.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
| [781. 森林中的兔子](https://leetcode-cn.com/problems/rabbits-in-forest/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/rabbits-in-forest/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-v17p5/) | 中等 | 🤩🤩🤩🤩 |
1515
| [881. 救生艇](https://leetcode-cn.com/problems/boats-to-save-people/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/boats-to-save-people/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-hosg8/) | 中等 | 🤩🤩🤩🤩 |
1616
| [995. K 连续位的最小翻转次数](https://leetcode-cn.com/problems/minimum-number-of-k-consecutive-bit-flips/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-number-of-k-consecutive-bit-flips/solution/po-su-tan-xin-jie-fa-yu-tan-xin-chai-fen-4lyy/) | 困难 | 🤩🤩🤩 |
17+
| [1005. K 次取反后最大化的数组和](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/solution/gong-shui-san-xie-jian-dan-fen-qing-kuan-6qwu/) | 简单 | 🤩🤩🤩🤩 |
1718
| [1218. 最长定差子序列](https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/solution/gong-shui-san-xie-jie-he-tan-xin-de-zhua-dj1k/) | 中等 | 🤩🤩🤩🤩🤩 |
1819
| [1221. 分割平衡字符串](https://leetcode-cn.com/problems/split-a-string-in-balanced-strings/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/split-a-string-in-balanced-strings/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-wumnk/) | 简单 | 🤩🤩🤩🤩 |
1920
| [1707. 与数组中元素的最大异或值](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/solution/gong-shui-san-xie-jie-zhe-ge-wen-ti-lai-lypqr/) | 困难 | 🤩🤩🤩 |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[1005. K 次取反后最大化的数组和](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/solution/gong-shui-san-xie-jian-dan-fen-qing-kuan-6qwu/)** ,难度为 **简单**
4+
5+
Tag : 「优先队列(堆)」、「模拟」、「贪心」
6+
7+
8+
9+
给你一个整数数组 `nums` 和一个整数 `k` ,按以下方法修改该数组:
10+
11+
* 选择某个下标 `i` 并将 `nums[i]` 替换为 `-nums[i]`
12+
13+
重复这个过程恰好 `k` 次。可以多次选择同一个下标 `i`
14+
15+
以这种方式修改数组后,返回数组 可能的最大和 。 
16+
17+
示例 1:
18+
```
19+
输入:nums = [4,2,3], k = 1
20+
21+
输出:5
22+
23+
解释:选择下标 1 ,nums 变为 [4,-2,3] 。
24+
```
25+
示例 2:
26+
```
27+
输入:nums = [3,-1,0,2], k = 3
28+
29+
输出:6
30+
31+
解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2] 。
32+
```
33+
示例 3:
34+
```
35+
输入:nums = [2,-3,-1,5,-4], k = 2
36+
37+
输出:13
38+
39+
解释:选择下标 (1, 4) ,nums 变为 [2,3,-1,5,4] 。
40+
```
41+
42+
提示:
43+
* $1 <= nums.length <= 10^4$
44+
* $-100 <= nums[i] <= 100$
45+
* $1 <= k <= 10^4$
46+
47+
---
48+
49+
### 贪心 + 分情况讨论 + 模拟
50+
51+
假设取反前的总和为 $sum$,取反一个任意值 $x$ 后,对 $sum$ 的影响为 $- 2 * x$。
52+
53+
即取反一个负数会使得结果变大,取反正数会使结果变小,取反 $0$ 值对结果没有影响。
54+
55+
因此,为了让取反后的结果尽可能的大,我们应当取反 $-2*x$ 尽可能大的数值。即按照「负数从小到大的顺序进行取反」。
56+
57+
对取反次数 $k$ 和 负数个数 $cnt$ 进行分情况讨论:
58+
59+
* $k <= cnt$:按照负数从小到大的顺序进行取反即可;
60+
* $k > cnt$:按照负数从小到大的顺序进行取反后,根据「是否存在 $0$ 值」和「剩余取反次数的奇偶性」进行分情况讨论:
61+
* 存在 $0$ 值 或 剩余取反次数为偶数:直接返回当前取反数组的总和( $0$ 值可抵消任意次数的取反操作,将偶数次的取反操作应用在同一数值上,结果不变);
62+
* 不存在 $0$ 值且剩余取反次数为奇数:此时从当前数值中取一个绝对值最小值(使用 $idx$ 记录该值下标)进行取反,得到最终的取反数组。
63+
64+
最后对取反数组进行求和操作即可。
65+
66+
代码:
67+
```Java
68+
class Solution {
69+
public int largestSumAfterKNegations(int[] nums, int k) {
70+
int n = nums.length, idx = 0;
71+
PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->nums[a]-nums[b]);
72+
boolean zero = false;
73+
for (int i = 0; i < n; i++) {
74+
if (nums[i] < 0) q.add(i);
75+
if (nums[i] == 0) zero = true;
76+
if (Math.abs(nums[i]) < Math.abs(nums[idx])) idx = i;
77+
}
78+
if (k <= q.size()) {
79+
while (k-- > 0) nums[q.peek()] = -nums[q.poll()];
80+
} else {
81+
while (!q.isEmpty() && k-- > 0) nums[q.peek()] = -nums[q.poll()];
82+
if (!zero && k % 2 != 0) nums[idx] = -nums[idx];
83+
}
84+
int ans = 0;
85+
for (int i : nums) ans += i;
86+
return ans;
87+
}
88+
}
89+
```
90+
* 时间复杂度:对 $nums$ 进行遍历,得到 $idx$ 以及优先队列的复杂度为 $O(n\log{n})$;从优先队列中取出元素进行取反操作的复杂度为 $O(k\log{n})$;对取反数组进行求和复杂度为 $O(n)$。整体复杂度为 $O(n\log{n})$
91+
* 空间复杂度:$O(n)$
92+
93+
---
94+
95+
### 优化优先队列
96+
97+
由于 $nums$ 长度范围为 $10000$,但值域范围在 $[-100, 100]$,因此我们可以使用计数数组 $cnt$ 来替代优先队列的作用。
98+
99+
注意由于 $nums[i]$ 存在负数,因此需要增 $100$ 的偏移量。同时对于翻转操作,仅需要修改相应计数即可。
100+
101+
代码:
102+
```Java
103+
class Solution {
104+
public int largestSumAfterKNegations(int[] nums, int k) {
105+
int[] cnts = new int[210];
106+
for (int i : nums) cnts[i + 100]++;
107+
for (int i = -100; i < 0 && k > 0; i++) {
108+
while (cnts[i + 100] != 0 && k-- > 0) {
109+
cnts[i + 100]--; cnts[-i + 100]++;
110+
}
111+
}
112+
if (cnts[0 + 100] == 0 && k > 0 && k % 2 != 0) {
113+
int val = 1;
114+
while (cnts[val + 100] == 0) val++;
115+
cnts[val + 100]--; cnts[-val + 100]++;
116+
}
117+
int ans = 0;
118+
for (int i = -100; i <= 100; i++) ans += i * cnts[i + 100];
119+
return ans;
120+
}
121+
}
122+
```
123+
* 时间复杂度:需要对 $nums$ 以及大小为 $C = 210$ 的计数数组进行常数次扫描,复杂度为 $O(n + C)$
124+
* 空间复杂度:$O(C)$
125+
126+
---
127+
128+
### 最后
129+
130+
这是我们「刷穿 LeetCode」系列文章的第 `No.1005` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
131+
132+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
133+
134+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
135+
136+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
137+

0 commit comments

Comments
 (0)