Skip to content

Commit 6643b8d

Browse files
Merge pull request SharingSource#664 from SharingSource/ac_oier
✨feat: add 517、451
2 parents 61078c3 + 9589965 commit 6643b8d

7 files changed

+235
-30
lines changed

Index/单调栈.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
| [496. 下一个更大元素 I](https://leetcode-cn.com/problems/next-greater-element-i/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/next-greater-element-i/solution/gong-shui-san-xie-yi-ti-shuang-jie-bian-n6nwz/) | 中等 | 🤩🤩🤩🤩 |
66
| [503. 下一个更大元素 II](https://leetcode-cn.com/problems/next-greater-element-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/next-greater-element-ii/solution/cong-po-su-jie-fa-de-jiao-du-qu-li-jie-d-trht/) | 中等 | 🤩🤩🤩 |
77
| [654. 最大二叉树](https://leetcode.cn/problems/maximum-binary-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-binary-tree/solution/by-ac_oier-s0wc/) | 中等 | 🤩🤩🤩🤩🤩 |
8+
| [907. 子数组的最小值之和](https://leetcode.cn/problems/sum-of-subarray-minimums/) | [LeetCode 题解链接](https://leetcode.cn/problems/sum-of-subarray-minimums/solution/by-ac_oier-h9cd/) | 中等 | 🤩🤩🤩🤩 |
89
| [1475. 商品折扣后的最终价格](https://leetcode.cn/problems/final-prices-with-a-special-discount-in-a-shop/) | [LeetCode 题解链接](https://leetcode.cn/problems/final-prices-with-a-special-discount-in-a-shop/solution/by-ac_oier-hw5b/) | 简单 | 🤩🤩🤩🤩🤩 |
910
| [2104. 子数组范围和](https://leetcode-cn.com/problems/sum-of-subarray-ranges/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-subarray-ranges/solution/gong-shui-san-xie-yi-ti-san-jie-qu-jian-wn84z/) | 中等 | 🤩🤩🤩🤩🤩 |
1011

Index/数学.md

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
| [829. 连续整数求和](https://leetcode.cn/problems/consecutive-numbers-sum/) | [LeetCode 题解链接](https://leetcode.cn/problems/consecutive-numbers-sum/solution/by-ac_oier-220q/) | 困难 | 🤩🤩🤩🤩 |
5454
| [869. 重新排序得到 2 的幂](https://leetcode-cn.com/problems/reordered-power-of-2/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reordered-power-of-2/solution/gong-shui-san-xie-yi-ti-shuang-jie-dfs-c-3s1e/) | 中等 | 🤩🤩🤩🤩 |
5555
| [879. 盈利计划](https://leetcode-cn.com/problems/profitable-schemes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/profitable-schemes/solution/gong-shui-san-xie-te-shu-duo-wei-fei-yon-7su9/) | 困难 | 🤩🤩🤩🤩🤩 |
56+
| [907. 子数组的最小值之和](https://leetcode.cn/problems/sum-of-subarray-minimums/) | [LeetCode 题解链接](https://leetcode.cn/problems/sum-of-subarray-minimums/solution/by-ac_oier-h9cd/) | 中等 | 🤩🤩🤩 |
5657
| [952. 按公因数计算最大组件大小](https://leetcode.cn/problems/largest-component-size-by-common-factor/) | [LeetCode 题解链接](https://leetcode.cn/problems/largest-component-size-by-common-factor/solution/by-ac_oier-mw04/) | 困难 | 🤩🤩🤩🤩🤩 |
5758
| [1006. 笨阶乘](https://leetcode-cn.com/problems/clumsy-factorial/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/clumsy-factorial/solution/gong-shui-san-xie-tong-yong-biao-da-shi-nngfp/) | 中等 | 🤩🤩🤩 |
5859
| [1037. 有效的回旋镖](https://leetcode.cn/problems/valid-boomerang/) | [LeetCode 题解链接](https://leetcode.cn/problems/valid-boomerang/solution/by-ac_oier-eory/) | 简单 | 🤩🤩🤩🤩🤩 |

Index/模拟.md

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
| [1486. 数组异或操作](https://leetcode-cn.com/problems/xor-operation-in-an-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/xor-operation-in-an-array/solution/gong-shui-san-xie-yi-ti-shuang-jie-mo-ni-dggg/) | 简单 | 🤩🤩🤩 |
161161
| [1518. 换酒问题](https://leetcode-cn.com/problems/water-bottles/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/water-bottles/solution/gong-shui-san-xie-yi-ti-shuang-jie-ji-sh-7yyo/) | 简单 | 🤩🤩🤩🤩 |
162162
| [1576. 替换所有的问号](https://leetcode-cn.com/problems/replace-all-s-to-avoid-consecutive-repeating-characters/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/replace-all-s-to-avoid-consecutive-repeating-characters/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-fa1u/) | 简单 | 🤩🤩🤩🤩🤩 |
163+
| [1582. 二进制矩阵中的特殊位置](https://leetcode.cn/problems/special-positions-in-a-binary-matrix/) | [LeetCode 题解链接](https://leetcode.cn/problems/special-positions-in-a-binary-matrix/solution/by-ac_oier-61w0/) | 简单 | 🤩🤩🤩🤩🤩 |
163164
| [1583. 统计不开心的朋友](https://leetcode-cn.com/problems/count-unhappy-friends/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-unhappy-friends/solution/gong-shui-san-xie-ha-xi-biao-mo-ni-ti-by-2qy0/) | 中等 | 🤩🤩🤩🤩 |
164165
| [1606. 找到处理最多请求的服务器](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/solution/by-ac_oier-zgm6/) | 困难 | 🤩🤩🤩🤩 |
165166
| [1614. 括号的最大嵌套深度](https://leetcode-cn.com/problems/maximum-nesting-depth-of-the-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-nesting-depth-of-the-parentheses/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-pf5d/) | 简单 | 🤩🤩🤩🤩🤩 |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[1582. 二进制矩阵中的特殊位置](https://leetcode.cn/problems/special-positions-in-a-binary-matrix/solution/by-ac_oier-61w0/)** ,难度为 **简单**
4+
5+
Tag : 「模拟」
6+
7+
8+
9+
给你一个大小为 `rows x cols` 的矩阵 `mat`,其中 `mat[i][j]``0``1`,请返回 矩阵 `mat` 中特殊位置的数目 。
10+
11+
特殊位置 定义:如果 `mat[i][j] = 1` 并且第 `i` 行和第 `j` 列中的所有其他元素均为 `0`(行和列的下标均 从 `0` 开始 ),则位置 `(i, j)` 被称为特殊位置。
12+
13+
示例 1:
14+
```
15+
输入:mat = [[1,0,0],
16+
  [0,0,1],
17+
  [1,0,0]]
18+
19+
输出:1
20+
21+
解释:(1,2) 是一个特殊位置,因为 mat[1][2] == 1 且所处的行和列上所有其他元素都是 0
22+
```
23+
示例 2:
24+
```
25+
输入:mat = [[1,0,0],
26+
  [0,1,0],
27+
  [0,0,1]]
28+
29+
输出:3
30+
31+
解释:(0,0), (1,1) 和 (2,2) 都是特殊位置
32+
```
33+
示例 3:
34+
```
35+
输入:mat = [[0,0,0,1],
36+
  [1,0,0,0],
37+
  [0,1,1,0],
38+
  [0,0,0,0]]
39+
40+
输出:2
41+
```
42+
示例 4:
43+
```
44+
输入:mat = [[0,0,0,0,0],
45+
  [1,0,0,0,0],
46+
  [0,1,0,0,0],
47+
  [0,0,1,0,0],
48+
  [0,0,0,1,1]]
49+
50+
输出:3
51+
```
52+
53+
提示:
54+
* $rows = mat.length$
55+
* $cols = mat[i].length$
56+
* $1 <= rows, cols <= 100$
57+
* $mat[i][j]$ 是 `0``1`
58+
59+
---
60+
61+
### 模拟
62+
63+
根据题意,使用数组 `r``c` 分别预处理除每行和每列所含 $1$ 的个数,复杂度为 $O(m \times n)$。
64+
65+
随后分别统计特殊位置的个数:满足 $mat[i][j] = 1$ 且 $r[i] = c[j] = 1$ 的位置。
66+
67+
Java 代码:
68+
```Java
69+
class Solution {
70+
public int numSpecial(int[][] mat) {
71+
int n = mat.length, m = mat[0].length, ans = 0;
72+
int[] r = new int[n], c = new int[m];
73+
for (int i = 0; i < n; i++) {
74+
for (int j = 0; j < m; j++) r[i] += mat[i][j];
75+
}
76+
for (int i = 0; i < m; i++) {
77+
for (int j = 0; j < n; j++) c[i] += mat[j][i];
78+
}
79+
for (int i = 0; i < n; i++) {
80+
for (int j = 0; j < m; j++) {
81+
if (mat[i][j] == 1 && r[i] == 1 && c[j] == 1) ans++;
82+
}
83+
}
84+
return ans;
85+
}
86+
}
87+
```
88+
TypeScript 代码:
89+
```TypeScript
90+
function numSpecial(mat: number[][]): number {
91+
let n = mat.length, m = mat[0].length, ans = 0
92+
const r = new Array<number>(n).fill(0), c = new Array<number>(m).fill(0)
93+
for (let i = 0; i < n; i++) {
94+
for (let j = 0; j < m; j++) r[i] += mat[i][j]
95+
}
96+
for (let i = 0; i < m; i++) {
97+
for (let j = 0; j < n; j++) c[i] += mat[j][i]
98+
}
99+
for (let i = 0; i < n; i++) {
100+
for (let j = 0; j < m; j++) {
101+
if (mat[i][j] == 1 && r[i] == 1 && c[j] == 1) ans++
102+
}
103+
}
104+
return ans
105+
};
106+
```
107+
* 时间复杂度:$O(m \times n)$
108+
* 空间复杂度:$O(m + n)$
109+
110+
---
111+
112+
### 最后
113+
114+
这是我们「刷穿 LeetCode」系列文章的第 `No.1582` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
115+
116+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
117+
118+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
119+
120+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
121+

LeetCode/451-460/451. 根据字符出现频率排序(中等).md

+13-27
Original file line numberDiff line numberDiff line change
@@ -46,50 +46,39 @@ Tag : 「模拟」、「桶排序」、「哈希表」、「数组」、「优
4646
注意'A'和'a'被认为是两种不同的字符。
4747
```
4848

49+
提示:
50+
* $1 <= s.length <= 5 \times 10^5$
51+
* `s` 由大小写英文字母和数字组成
52+
4953
---
5054

5155
### 数据结构 + 模拟
5256

5357
这是一道考察数据结构运用的模拟题。
5458

5559
具体做法如下:
56-
5760
1. 先使用「哈希表」对词频进行统计;
5861
2. 遍历统计好词频的哈希表,将每个键值对以 `{字符,词频}` 的形式存储到「优先队列(堆)」中。并规定「优先队列(堆)」排序逻辑为:
5962
* 如果 `词频` 不同,则按照 `词频` 倒序;
6063
* 如果 `词频` 相同,则根据 `字符字典序` 升序(由于本题采用 Special Judge 机制,这个排序策略随意调整也可以。但通常为了确保排序逻辑满足「全序关系」,这个地方可以写正写反,但理论上不能不写,否则不能确保每次排序结果相同);
6164
3. 从「优先队列(堆)」依次弹出,构造答案。
6265

63-
![image.png](https://pic.leetcode-cn.com/1625273052-MtkpTv-image.png)
64-
6566
代码:
6667
```Java
6768
class Solution {
68-
class Node {
69-
char c;
70-
int v;
71-
Node(char _c, int _v) {
72-
c = _c; v = _v;
73-
}
74-
}
7569
public String frequencySort(String s) {
7670
char[] cs = s.toCharArray();
7771
Map<Character, Integer> map = new HashMap<>();
78-
for (char c : cs) {
79-
map.put(c, map.getOrDefault(c, 0) + 1);
80-
}
81-
PriorityQueue<Node> q = new PriorityQueue<>((a,b)->{
82-
if (b.v != a.v) return b.v - a.v;
83-
return a.c - b.c;
72+
for (char c : cs) map.put(c, map.getOrDefault(c, 0) + 1);
73+
PriorityQueue<int[]> q = new PriorityQueue<>((a,b)->{
74+
return a[1] != b[1] ? b[1] - a[1] : a[0] - b[0];
8475
});
85-
for (char c : map.keySet()) {
86-
q.add(new Node(c, map.get(c)));
87-
}
76+
for (char c : map.keySet()) q.add(new int[]{c, map.get(c)});
8877
StringBuilder sb = new StringBuilder();
8978
while (!q.isEmpty()) {
90-
Node poll = q.poll();
91-
int k = poll.v;
92-
while (k-- > 0) sb.append(poll.c);
79+
int[] poll = q.poll();
80+
int c = poll[0], k = poll[1];
81+
while (k-- > 0) sb.append((char)(c));
9382
}
9483
return sb.toString();
9584
}
@@ -106,8 +95,6 @@ class Solution {
10695

10796
具体的,利用 ASCII 字符集共 $128$ 位,预先建立一个大小为 $128$ 的数组,利用「桶排序」的思路替代「哈希表」和「优先队列(堆)」的作用。
10897

109-
![image.png](https://pic.leetcode-cn.com/1625273079-aeNBlb-image.png)
110-
11198
代码:
11299
```Java
113100
class Solution {
@@ -117,8 +104,7 @@ class Solution {
117104
for (int i = 0; i < 128; i++) cnts[i][0] = i;
118105
for (char c : cs) cnts[c][1]++;
119106
Arrays.sort(cnts, (a, b)->{
120-
if (a[1] != b[1]) return b[1] - a[1];
121-
return a[0] - b[0];
107+
return a[1] != b[1] ? b[1] - a[1] : a[0] - b[0];
122108
});
123109
StringBuilder sb = new StringBuilder();
124110
for (int i = 0; i < 128; i++) {
@@ -130,7 +116,7 @@ class Solution {
130116
}
131117
}
132118
```
133-
* 时间复杂度:令字符集的大小为 $C$复杂度为 $O(\max(n, C\log{C}))$
119+
* 时间复杂度:令字符集的大小为 $C$复杂度为 $O(\max(n, C\log{C}))$
134120
* 空间复杂度:$O(n + C + \log{C})$
135121

136122
---

LeetCode/571-580/517. 超级洗衣机(困难).md renamed to LeetCode/511-520/517. 超级洗衣机(困难).md

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ Tag : 「贪心算法」
4242
```
4343

4444
提示:
45-
* n == machines.length
46-
* 1 <= n <= $10^4$
47-
* 0 <= machines[i] <= $10^5$
45+
* $n = machines.length$
46+
* $1 <= n <= 10^4$
47+
* $0 <= machines[i] <= 10^5$
4848

4949
---
5050

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[908. 最小差值 I](https://leetcode.cn/problems/sum-of-subarray-minimums/solution/by-ac_oier-h9cd/)** ,难度为 **中等**
4+
5+
Tag : 「数学」、「单调栈」
6+
7+
8+
9+
给定一个整数数组 `arr`,找到 `min(b)` 的总和,其中 `b` 的范围为 `arr` 的每个(连续)子数组。
10+
11+
由于答案可能很大,因此 返回答案模 $10^9 + 7$ 。
12+
13+
示例 1:
14+
```
15+
输入:arr = [3,1,2,4]
16+
17+
输出:17
18+
19+
解释:
20+
子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4],[3,1,2,4]。
21+
最小值为 3,1,2,4,1,1,2,1,1,1,和为 17。
22+
```
23+
示例 2:
24+
```
25+
输入:arr = [11,81,94,43,3]
26+
27+
输出:444
28+
```
29+
30+
提示:
31+
* $1 <= arr.length <= 3 \times 10^4$
32+
* $1 <= arr[i] <= 3 \times 10^4$
33+
34+
---
35+
36+
### 单调栈 + 数学
37+
38+
原问题为求所有子数组的最小值之和,其可等价为求每个 $arr[i]$ 对答案的贡献,即每个 $arr[i]$ 可作为多少个子数组的最小值。
39+
40+
假定我们能预处理出两数组 `l``r` 分别代表 $arr[i]$ 作为子数组最小值时,其所能到达的最远两端:
41+
* `l[i] = a` 代表下标 $a$ 为 $arr[i]$ 能够作为子数组最小值时的最远左边界,即为 $arr[i]$ 左边第一个比其小的元素(若不存在,则为 $a = -1$)
42+
* `r[i] = b` 代表跳表 $b$ 为 $arr[i]$ 能够作为子数组最小值时的最远右边界,即为 $arr[i]$ 右边第一个比其小的元素(若不存在,则为 $b = n$)
43+
44+
子数组左端点个数为 $(i - a)$ 个,右端点个数为 $(b - i)$ 个,根据乘法原理可知,子数组个数为两者乘积,每个子数组对答案的贡献为 $arr[i]$。
45+
46+
由于 `arr` 可能有重复元素,我们需要考虑取左右端点时,是取成「小于等于」还是「严格小于」:
47+
* 若两端均取成严格小于,且两端中间存在与 $arr[i]$ 等值元素,会导致相同子数组被重复统计;
48+
* 若两端均取成小于等于,且两端恰好存在与 $arr[i]$ 等值元素,会导致原本可以被添加到子数组的等值元素漏加;
49+
* 若一端取成严格小于,另一端取成小于等于,可确保不重不漏。
50+
51+
至于预处理 `l``r` 则可以使用「单调栈」求解。
52+
53+
代码:
54+
```Java
55+
class Solution {
56+
int MOD = (int)1e9+7;
57+
public int sumSubarrayMins(int[] arr) {
58+
int n = arr.length;
59+
int[] l = new int[n], r = new int[n];
60+
Arrays.fill(l, -1); Arrays.fill(r, n);
61+
Deque<Integer> d = new ArrayDeque<>();
62+
for (int i = 0; i < n; i++) {
63+
while (!d.isEmpty() && arr[d.peekLast()] >= arr[i]) r[d.pollLast()] = i;
64+
d.addLast(i);
65+
}
66+
d.clear();
67+
for (int i = n - 1; i >= 0; i--) {
68+
while (!d.isEmpty() && arr[d.peekLast()] > arr[i]) l[d.pollLast()] = i;
69+
d.addLast(i);
70+
}
71+
long ans = 0;
72+
for (int i = 0; i < n; i++) {
73+
int a = l[i], b = r[i];
74+
ans += (i - a) * 1L * (b - i) % MOD * arr[i] % MOD;
75+
ans %= MOD;
76+
}
77+
return (int) ans;
78+
}
79+
}
80+
```
81+
* 时间复杂度:$O(n)$
82+
* 空间复杂度:$O(n)$
83+
84+
---
85+
86+
### 最后
87+
88+
这是我们「刷穿 LeetCode」系列文章的第 `No.907` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
89+
90+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
91+
92+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
93+
94+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
95+

0 commit comments

Comments
 (0)