Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f1acc88

Browse files
✨feat: add 927
1 parent c0e35cd commit f1acc88

File tree

3 files changed

+131
-1
lines changed

3 files changed

+131
-1
lines changed

‎Index/模拟.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
| [905. 按奇偶排序数组](https://leetcode-cn.com/problems/sort-array-by-parity/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sort-array-by-parity/solution/by-ac_oier-nuz7/) | 简单 | 🤩🤩🤩 |
123123
| [919. 完全二叉树插入器](https://leetcode.cn/problems/complete-binary-tree-inserter/) | [LeetCode 题解链接](https://leetcode.cn/problems/complete-binary-tree-inserter/solution/by-ac_oier-t9dh/) | 中等 | 🤩🤩🤩🤩 |
124124
| [921. 使括号有效的最少添加](https://leetcode.cn/problems/minimum-add-to-make-parentheses-valid/) | [LeetCode 题解链接](https://leetcode.cn/problems/minimum-add-to-make-parentheses-valid/solution/by-ac_oier-9tn1/) | 中等 | 🤩🤩🤩🤩 |
125+
| [927. 三等分](https://leetcode.cn/problems/three-equal-parts/) | [LeetCode 题解链接](https://leetcode.cn/problems/three-equal-parts/solution/by-ac_oier-9i2s/) | 困难 | 🤩🤩🤩🤩 |
125126
| [929. 独特的电子邮件地址](https://leetcode.cn/problems/unique-email-addresses/) | [LeetCode 题解链接](https://leetcode.cn/problems/unique-email-addresses/solution/by-ac_oier-d3zu/) | 简单 | 🤩🤩🤩 |
126127
| [944. 删列造序](https://leetcode.cn/problems/delete-columns-to-make-sorted/) | [LeetCode 题解链接](https://leetcode.cn/problems/delete-columns-to-make-sorted/solution/by-ac_oier-smoz/) | 简单 | 🤩🤩🤩 |
127128
| [946. 验证栈序列](https://leetcode.cn/problems/validate-stack-sequences/) | [LeetCode 题解链接](https://leetcode.cn/problems/validate-stack-sequences/solution/by-ac_oier-84qd/) | 中等 | 🤩🤩🤩🤩 |

‎LeetCode/281-290/287. 寻找重复数(中等).md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
这是 LeetCode 上的 **[287. 寻找重复数](https://leetcode.cn/problems/find-the-duplicate-number/solution/by-ac_oier-az8v/)** ,难度为 **中等**
44

5-
Tag : 「原地哈希」
5+
Tag : 「桶排序」、「原地哈希」
66

77

88

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[927. 三等分](https://leetcode.cn/problems/three-equal-parts/solution/by-ac_oier-9i2s/)** ,难度为 **困难**
4+
5+
Tag : 「模拟」
6+
7+
8+
9+
给定一个由 `0``1` 组成的数组 `arr`,将数组分成 `3` 个非空的部分 ,使得所有这些部分表示相同的二进制值。
10+
11+
如果可以做到,请返回任何 `[i, j]`,其中 `i+1 < j`,这样一来:
12+
13+
* `arr[0], arr[1], ..., arr[i]` 为第一部分;
14+
* `arr[i + 1], arr[i + 2], ..., arr[j - 1]` 为第二部分;
15+
* `arr[j], arr[j + 1], ..., arr[arr.length - 1]` 为第三部分。
16+
* 这三个部分所表示的二进制值相等。
17+
18+
如果无法做到,就返回 `[-1, -1]`
19+
20+
注意,在考虑每个部分所表示的二进制时,应当将其看作一个整体。例如,`[1,1,0]` 表示十进制中的 `6`,而不会是 `3`。此外,前导零也是被允许的,所以 `[0,1,1]``[1,1]` 表示相同的值。
21+
22+
示例 1:
23+
```
24+
输入:arr = [1,0,1,0,1]
25+
26+
输出:[0,3]
27+
```
28+
示例 2:
29+
```
30+
输入:arr = [1,1,0,1,1]
31+
32+
输出:[-1,-1]
33+
```
34+
示例 3:
35+
```
36+
输入:arr = [1,1,0,0,1]
37+
38+
输出:[0,2]
39+
```
40+
41+
提示:
42+
* 3ドル <= arr.length <= 3 \times 10^4$
43+
* `arr[i]``0``1`
44+
45+
---
46+
47+
### 模拟
48+
49+
心情不好,写的代码也不好。
50+
51+
就大概讲讲啥意思吧:
52+
53+
1. 先统计 `1` 的个数 `cnt`,若 `cnt = 0` 代表能够任意划分,直接返回 `[0, 2]`;
54+
2.`cnt` 不为 3ドル$ 的倍数,必然不能正常划分,返回无解 `[-1, -1]`,否则可知三段中必然每一段 `1` 的数量均为 $t = \frac{cnt}{3}$ 个;
55+
3. 最后检查「三段中 `1` 的间隔位是否相同,后缀 `0` 个数是否相同」即可:
56+
1. 创建二维数组 `ins` 记录三段中,相邻 `1` 之间的间隔情况,若存在间隔 `1` 不同,返回无解 `[-1, -1]`;
57+
2. 预处理四个变量 `l1``l2``r1``r2`,分别代表能够划分出最左边 `t``1` 的左右端点,以及能够划分出最右边 `t``1` 的左右端点,同时统计最后一段的后缀 `0` 的数量 `d`,配合四个变量来检查能否划分出具有 `d` 个后缀 `0` 的前两段。
58+
59+
代码:
60+
```Java
61+
class Solution {
62+
public int[] threeEqualParts(int[] arr) {
63+
int[] fail = new int[]{-1, -1};
64+
// 检查总数
65+
int n = arr.length, cnt = 0;
66+
for (int i = 0; i < n; i++) cnt += arr[i];
67+
if (cnt == 0) return new int[]{0, 2};
68+
if (cnt % 3 != 0) return fail;
69+
// 检查间隔相对位
70+
int t = cnt / 3;
71+
int[][] ins = new int[3][t];
72+
for (int i = 0, j = -1, k = 0, p = 0, idx = 0; i < n; i++) {
73+
if (arr[i] == 0) continue;
74+
if (j != -1) ins[p][idx++] = i - j;
75+
if (++k == t) {
76+
j = -1; k = 0; p++; idx = 0;
77+
} else {
78+
j = i;
79+
}
80+
}
81+
for (int i = 0; i < t; i++) {
82+
if (ins[0][i] == ins[1][i] && ins[0][i] == ins[2][i] && ins[1][i] == ins[2][i]) continue;
83+
return fail;
84+
}
85+
// 构造答案(l1 和 l2 分别为能够划分出最左边 t 个 1 的 左右端点;r1 和 r2 分别为能够划分出最右边 t 个 1 的左右端点)
86+
int l1 = -1, l2 = -1, r1 = -1, r2 = -1;
87+
for (int i = 0, k = 0; i < n; i++) {
88+
k += arr[i];
89+
if (k == t) {
90+
if (l1 == -1) l1 = i;
91+
} else if (k == t + 1) {
92+
l2 = i - 1;
93+
break;
94+
}
95+
}
96+
for (int i = n - 1, k = 0; i >= 0; i--) {
97+
k += arr[i];
98+
if (k == t) {
99+
if (r2 == -1) r2 = i;
100+
} else if (k == t + 1) {
101+
r1 = i + 1;
102+
break;
103+
}
104+
}
105+
int d = 0; // d 为最右边一段的后缀 0 的数量
106+
for (int i = n - 1; i >= 0; i--) {
107+
if (arr[i] == 1) break;
108+
d++;
109+
}
110+
if (l1 + d > l2 || r1 + d > r2) return fail;
111+
return new int[]{l1 + d, r1 + d};
112+
}
113+
}
114+
```
115+
* 时间复杂度:$O(n)$
116+
* 空间复杂度:$O(n)$
117+
118+
---
119+
120+
### 最后
121+
122+
这是我们「刷穿 LeetCode」系列文章的第 `No.927` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
123+
124+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
125+
126+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
127+
128+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
129+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /