57
57
58
58
<!-- 这里可写通用的实现逻辑 -->
59
59
60
- ** 方法一:将 1 的数量三等分 **
60
+ ** 方法一:计数 + 三指针 **
61
61
62
- 将 $1$ 的数量三等分,找到每一部分的第一个 $1$,分别记为 $i$, $j$, $k $。
62
+ 我们记数组的长度为 $n$,数组中 $1$ 的数量为 $cnt $。
63
63
64
- 然后从 $i$, $j$, $k$ 开始往后同时遍历每一部分,判断三部分对应的值是否相等,是则继续遍历,直至 $k$ 到达 $arr$ 末尾 。
64
+ 显然 $cnt$ 必须是 $3$ 的倍数,否则无法将数组三等分,可以提前返回 $ [ -1, -1 ] $。如果 $cnt$ 为 $0$,那么意味着数组中所有元素都为 $0$,直接返回 $ [ 0, n - 1 ] $ 即可 。
65
65
66
- 遍历结束时,若 $k=n$,说明满足三等分,返回此时的 $ [ i-1,j ] $ 作为答案 。
66
+ 我们将 $cnt$ 除以 $3$,得到每一份中 $1$ 的数量,然后找到每一份的第一个 $1$ 在数组 ` arr ` 中的位置(参考以下代码中的 $find(x)$ 函数),分别记为 $i$, $j$, $k$ 。
67
67
68
- 时间复杂度 $O(n)$,其中 $n$ 表示 $arr$ 的长度。
68
+ ``` bash
69
+ 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0
70
+ ^ ^ ^
71
+ i j k
72
+ ```
73
+
74
+ 接着我们从 $i$, $j$, $k$ 开始往后同时遍历每一部分,判断三部分对应的值是否相等,是则继续遍历,直至 $k$ 到达 $arr$ 末尾。
75
+
76
+ ``` bash
77
+ 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0
78
+ ^ ^ ^
79
+ i j k
80
+ ```
81
+
82
+ 遍历结束时,若 $k=n$,说明满足三等分,返回此时的 $[ i - 1, j] $ 作为答案,否则返回 $[ -1, -1] $。
83
+
84
+ 时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 表示 ` arr ` 的长度。
69
85
70
86
<!-- tabs:start -->
71
87
76
92
``` python
77
93
class Solution :
78
94
def threeEqualParts (self , arr : List[int ]) -> List[int ]:
79
- def find (cnt ):
95
+ def find (x ):
80
96
s = 0
81
97
for i, v in enumerate (arr):
82
98
s += v
83
- if s == cnt :
99
+ if s == x :
84
100
return i
85
- return - 1
86
101
87
102
n = len (arr)
88
103
cnt, mod = divmod (sum (arr), 3 )
89
104
if mod:
90
105
return [- 1 , - 1 ]
91
106
if cnt == 0 :
92
107
return [0 , n - 1 ]
93
- i = find(1 )
94
- j = find(cnt + 1 )
95
- k = find(cnt * 2 + 1 )
108
+
109
+ i, j, k = find(1 ), find(cnt + 1 ), find(cnt * 2 + 1 )
96
110
while k < n and arr[i] == arr[j] == arr[k]:
97
111
i, j, k = i + 1 , j + 1 , k + 1
98
- if k == n:
99
- return [i - 1 , j]
100
- return [- 1 , - 1 ]
112
+ return [i - 1 , j] if k == n else [- 1 , - 1 ]
101
113
```
102
114
103
115
### ** Java**
@@ -106,43 +118,38 @@ class Solution:
106
118
107
119
``` java
108
120
class Solution {
121
+ private int [] arr;
122
+
109
123
public int [] threeEqualParts (int [] arr ) {
124
+ this . arr = arr;
125
+ int cnt = 0 ;
110
126
int n = arr. length;
111
- int cnt1 = 0 ;
112
127
for (int v : arr) {
113
- cnt1 += v;
128
+ cnt += v;
114
129
}
115
- int cnt = cnt1 / 3 ;
116
- int mod = cnt1 % 3 ;
117
- if (mod != 0 ) {
118
- return new int [] {- 1 , - 1 };
130
+ if (cnt % 3 != 0 ) {
131
+ return new int []{- 1 , - 1 };
119
132
}
120
133
if (cnt == 0 ) {
121
- return new int [] {0 , n - 1 };
122
- }
123
- int i = find(arr, 1 );
124
- int j = find(arr, cnt + 1 );
125
- int k = find(arr, cnt * 2 + 1 );
126
- while (k < n && arr[i] == arr[j] && arr[j] == arr[k]) {
127
- ++ i;
128
- ++ j;
129
- ++ k;
134
+ return new int []{0 , n - 1 };
130
135
}
131
- if (k == n) {
132
- return new int [] {i - 1 , j};
136
+ cnt /= 3 ;
137
+
138
+ int i = find(1 ), j = find(cnt + 1 ), k = find(cnt * 2 + 1 );
139
+ for (; k < n && arr[i] == arr[j] && arr[j] == arr[k]; ++ i, ++ j, ++ k) {
133
140
}
134
- return new int [] {- 1 , - 1 };
141
+ return k == n ? new int []{i - 1 , j} : new int [] {- 1 , - 1 };
135
142
}
136
143
137
- private int find (int [] arr , int cnt ) {
144
+ private int find (int x ) {
138
145
int s = 0 ;
139
146
for (int i = 0 ; i < arr. length; ++ i) {
140
147
s += arr[i];
141
- if (s == cnt ) {
148
+ if (s == x ) {
142
149
return i;
143
150
}
144
151
}
145
- return - 1 ;
152
+ return 0 ;
146
153
}
147
154
}
148
155
```
@@ -154,30 +161,22 @@ class Solution {
154
161
public:
155
162
vector<int > threeEqualParts(vector<int >& arr) {
156
163
int n = arr.size();
157
- int cnt1 = accumulate(arr.begin(), arr.end(), 0);
158
- int cnt = cnt1 / 3;
159
- int mod = cnt1 % 3;
160
- if (mod) return {-1, -1};
161
- if (cnt == 0) return {0, n - 1};
162
- int i = find(arr, 1);
163
- int j = find(arr, cnt + 1);
164
- int k = find(arr, cnt * 2 + 1);
165
- while (k < n && arr[ i] == arr[ j] && arr[ j] == arr[ k] ) {
166
- ++i;
167
- ++j;
168
- ++k;
169
- }
170
- if (k == n) return {i - 1, j};
171
- return {-1, -1};
172
- }
173
-
174
- int find(vector<int>& arr, int cnt) {
175
- int s = 0;
176
- for (int i = 0; i < arr.size(); ++i) {
177
- s += arr[i];
178
- if (s == cnt) return i;
179
- }
180
- return -1 ;
164
+ int cnt = accumulate(arr.begin(), arr.end(), 0);
165
+ if (cnt % 3) return {-1, -1};
166
+ if (!cnt) return {0, n - 1};
167
+ cnt /= 3;
168
+
169
+ auto find = [&](int x) {
170
+ int s = 0;
171
+ for (int i = 0; i < n; ++i) {
172
+ s += arr[i];
173
+ if (s == x) return i;
174
+ }
175
+ return 0 ;
176
+ };
177
+ int i = find(1 ), j = find(cnt + 1 ), k = find(cnt * 2 + 1 );
178
+ for (; k < n && arr[i] == arr[j] && arr[j] == arr[k]; ++i, ++j, ++k) {}
179
+ return k == n ? vector<int >{i - 1, j} : vector<int >{-1, -1};
181
180
}
182
181
};
183
182
```
@@ -186,34 +185,30 @@ public:
186
185
187
186
``` go
188
187
func threeEqualParts (arr []int ) []int {
188
+ find := func (x int ) int {
189
+ s := 0
190
+ for i , v := range arr {
191
+ s += v
192
+ if s == x {
193
+ return i
194
+ }
195
+ }
196
+ return 0
197
+ }
189
198
n := len (arr)
190
- cnt1 := 0
199
+ cnt := 0
191
200
for _ , v := range arr {
192
- cnt1 += v
201
+ cnt += v
193
202
}
194
- cnt := cnt1 / 3
195
- mod := cnt1 % 3
196
- if mod != 0 {
203
+ if cnt%3 != 0 {
197
204
return []int {-1 , -1 }
198
205
}
199
206
if cnt == 0 {
200
207
return []int {0 , n - 1 }
201
208
}
202
- find := func (cnt int ) int {
203
- s := 0
204
- for i , v := range arr {
205
- s += v
206
- if s == cnt {
207
- return i
208
- }
209
- }
210
- return -1
211
- }
209
+ cnt /= 3
212
210
i , j , k := find (1 ), find (cnt+1 ), find (cnt*2 +1 )
213
- for k < n && arr[i] == arr[j] && arr[j] == arr[k] {
214
- i++
215
- j++
216
- k++
211
+ for ; k < n && arr[i] == arr[j] && arr[j] == arr[k]; i, j, k = i+1 , j+1 , k+1 {
217
212
}
218
213
if k == n {
219
214
return []int {i - 1 , j}
@@ -222,6 +217,42 @@ func threeEqualParts(arr []int) []int {
222
217
}
223
218
```
224
219
220
+ ### ** JavaScript**
221
+
222
+ ``` js
223
+ /**
224
+ * @param {number[]} arr
225
+ * @return {number[]}
226
+ */
227
+ var threeEqualParts = function (arr ) {
228
+ function find (x ) {
229
+ let s = 0 ;
230
+ for (let i = 0 ; i < n; ++ i) {
231
+ s += arr[i];
232
+ if (s == x) {
233
+ return i;
234
+ }
235
+ }
236
+ return 0 ;
237
+ }
238
+ const n = arr .length ;
239
+ let cnt = 0 ;
240
+ for (const v of arr) {
241
+ cnt += v;
242
+ }
243
+ if (cnt % 3 ) {
244
+ return [- 1 , - 1 ];
245
+ }
246
+ if (cnt == 0 ) {
247
+ return [0 , n - 1 ];
248
+ }
249
+ cnt = Math .floor (cnt / 3 );
250
+ let [i, j, k] = [find (1 ), find (cnt + 1 ), find (cnt * 2 + 1 )];
251
+ for (; k < n && arr[i] == arr[j] && arr[j] == arr[k]; ++ i, ++ j, ++ k) {}
252
+ return k == n ? [i - 1 , j] : [- 1 , - 1 ];
253
+ };
254
+ ```
255
+
225
256
### ** ...**
226
257
227
258
```
0 commit comments