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 8d46bfa

Browse files
feat: add solutions to lc problem: No.3388 (doocs#3862)
No.3388.Count Beautiful Splits in an Array
1 parent 9a58a53 commit 8d46bfa

File tree

7 files changed

+396
-8
lines changed

7 files changed

+396
-8
lines changed

‎solution/3300-3399/3388.Count Beautiful Splits in an Array/README.md‎

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,32 +76,165 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3388.Co
7676

7777
<!-- solution:start -->
7878

79-
### 方法一
79+
### 方法一:LCP + 枚举
80+
81+
我们可以预处理 $\text{LCP}[i][j]$ 表示 $\textit{nums}[i:]$ 和 $\textit{nums}[j:]$ 的最长公共前缀长度。初始时 $\text{LCP}[i][j] = 0$。
82+
83+
接下来,我们倒序枚举 $i$ 和 $j,ドル对于每一对 $i$ 和 $j,ドル如果 $\textit{nums}[i] = \textit{nums}[j],ドル那么我们可以得到 $\text{LCP}[i][j] = \text{LCP}[i + 1][j + 1] + 1$。
84+
85+
最后,我们枚举第一个子数组的结尾位置 $i$(不包括位置 $i$),以及第二个子数组的结尾位置 $j$(不包括位置 $j$),那么第一个子数组的长度为 $i,ドル第二个子数组的长度为 $j - i,ドル第三个子数组的长度为 $n - j$。如果 $i \leq j - i$ 且 $\text{LCP}[0][i] \geq i,ドル或者 $j - i \leq n - j$ 且 $\text{LCP}[i][j] \geq j - i,ドル那么这个分割是美丽的,答案加一。
86+
87+
枚举结束后,答案即为美丽的分割数目。
88+
89+
时间复杂度 $O(n^2),ドル空间复杂度 $O(n^2)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
8090

8191
<!-- tabs:start -->
8292

8393
#### Python3
8494

8595
```python
86-
96+
class Solution:
97+
def beautifulSplits(self, nums: List[int]) -> int:
98+
n = len(nums)
99+
lcp = [[0] * (n + 1) for _ in range(n + 1)]
100+
for i in range(n - 1, -1, -1):
101+
for j in range(n - 1, i - 1, -1):
102+
if nums[i] == nums[j]:
103+
lcp[i][j] = lcp[i + 1][j + 1] + 1
104+
ans = 0
105+
for i in range(1, n - 1):
106+
for j in range(i + 1, n):
107+
a = i <= j - i and lcp[0][i] >= i
108+
b = j - i <= n - j and lcp[i][j] >= j - i
109+
ans += int(a or b)
110+
return ans
87111
```
88112

89113
#### Java
90114

91115
```java
92-
116+
class Solution {
117+
public int beautifulSplits(int[] nums) {
118+
int n = nums.length;
119+
int[][] lcp = new int[n + 1][n + 1];
120+
121+
for (int i = n - 1; i >= 0; i--) {
122+
for (int j = n - 1; j > i; j--) {
123+
if (nums[i] == nums[j]) {
124+
lcp[i][j] = lcp[i + 1][j + 1] + 1;
125+
}
126+
}
127+
}
128+
129+
int ans = 0;
130+
for (int i = 1; i < n - 1; i++) {
131+
for (int j = i + 1; j < n; j++) {
132+
boolean a = (i <= j - i) && (lcp[0][i] >= i);
133+
boolean b = (j - i <= n - j) && (lcp[i][j] >= j - i);
134+
if (a || b) {
135+
ans++;
136+
}
137+
}
138+
}
139+
140+
return ans;
141+
}
142+
}
93143
```
94144

95145
#### C++
96146

97147
```cpp
98-
148+
class Solution {
149+
public:
150+
int beautifulSplits(vector<int>& nums) {
151+
int n = nums.size();
152+
vector<vector<int>> lcp(n + 1, vector<int>(n + 1, 0));
153+
154+
for (int i = n - 1; i >= 0; i--) {
155+
for (int j = n - 1; j > i; j--) {
156+
if (nums[i] == nums[j]) {
157+
lcp[i][j] = lcp[i + 1][j + 1] + 1;
158+
}
159+
}
160+
}
161+
162+
int ans = 0;
163+
for (int i = 1; i < n - 1; i++) {
164+
for (int j = i + 1; j < n; j++) {
165+
bool a = (i <= j - i) && (lcp[0][i] >= i);
166+
bool b = (j - i <= n - j) && (lcp[i][j] >= j - i);
167+
if (a || b) {
168+
ans++;
169+
}
170+
}
171+
}
172+
173+
return ans;
174+
}
175+
};
99176
```
100177

101178
#### Go
102179

103180
```go
181+
func beautifulSplits(nums []int) (ans int) {
182+
n := len(nums)
183+
lcp := make([][]int, n+1)
184+
for i := range lcp {
185+
lcp[i] = make([]int, n+1)
186+
}
187+
188+
for i := n - 1; i >= 0; i-- {
189+
for j := n - 1; j > i; j-- {
190+
if nums[i] == nums[j] {
191+
lcp[i][j] = lcp[i+1][j+1] + 1
192+
}
193+
}
194+
}
195+
196+
for i := 1; i < n-1; i++ {
197+
for j := i + 1; j < n; j++ {
198+
a := i <= j-i && lcp[0][i] >= i
199+
b := j-i <= n-j && lcp[i][j] >= j-i
200+
if a || b {
201+
ans++
202+
}
203+
}
204+
}
205+
206+
return
207+
}
208+
```
104209

210+
#### TypeScript
211+
212+
```ts
213+
function beautifulSplits(nums: number[]): number {
214+
const n = nums.length;
215+
const lcp: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
216+
217+
for (let i = n - 1; i >= 0; i--) {
218+
for (let j = n - 1; j > i; j--) {
219+
if (nums[i] === nums[j]) {
220+
lcp[i][j] = lcp[i + 1][j + 1] + 1;
221+
}
222+
}
223+
}
224+
225+
let ans = 0;
226+
for (let i = 1; i < n - 1; i++) {
227+
for (let j = i + 1; j < n; j++) {
228+
const a = i <= j - i && lcp[0][i] >= i;
229+
const b = j - i <= n - j && lcp[i][j] >= j - i;
230+
if (a || b) {
231+
ans++;
232+
}
233+
}
234+
}
235+
236+
return ans;
237+
}
105238
```
106239

107240
<!-- tabs:end -->

‎solution/3300-3399/3388.Count Beautiful Splits in an Array/README_EN.md‎

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,32 +74,165 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3388.Co
7474

7575
<!-- solution:start -->
7676

77-
### Solution 1
77+
### Solution 1: LCP + Enumeration
78+
79+
We can preprocess $\text{LCP}[i][j]$ to represent the length of the longest common prefix of $\textit{nums}[i:]$ and $\textit{nums}[j:]$. Initially, $\text{LCP}[i][j] = 0$.
80+
81+
Next, we enumerate $i$ and $j$ in reverse order. For each pair of $i$ and $j,ドル if $\textit{nums}[i] = \textit{nums}[j],ドル then we can get $\text{LCP}[i][j] = \text{LCP}[i + 1][j + 1] + 1$.
82+
83+
Finally, we enumerate the ending position $i$ of the first subarray (excluding position $i$) and the ending position $j$ of the second subarray (excluding position $j$). The length of the first subarray is $i,ドル the length of the second subarray is $j - i,ドル and the length of the third subarray is $n - j$. If $i \leq j - i$ and $\text{LCP}[0][i] \geq i,ドル or $j - i \leq n - j$ and $\text{LCP}[i][j] \geq j - i,ドル then this split is beautiful, and we increment the answer by one.
84+
85+
After enumerating, the answer is the number of beautiful splits.
86+
87+
The time complexity is $O(n^2),ドル and the space complexity is $O(n^2)$. Here, $n$ is the length of the array $\textit{nums}$.
7888

7989
<!-- tabs:start -->
8090

8191
#### Python3
8292

8393
```python
84-
94+
class Solution:
95+
def beautifulSplits(self, nums: List[int]) -> int:
96+
n = len(nums)
97+
lcp = [[0] * (n + 1) for _ in range(n + 1)]
98+
for i in range(n - 1, -1, -1):
99+
for j in range(n - 1, i - 1, -1):
100+
if nums[i] == nums[j]:
101+
lcp[i][j] = lcp[i + 1][j + 1] + 1
102+
ans = 0
103+
for i in range(1, n - 1):
104+
for j in range(i + 1, n):
105+
a = i <= j - i and lcp[0][i] >= i
106+
b = j - i <= n - j and lcp[i][j] >= j - i
107+
ans += int(a or b)
108+
return ans
85109
```
86110

87111
#### Java
88112

89113
```java
90-
114+
class Solution {
115+
public int beautifulSplits(int[] nums) {
116+
int n = nums.length;
117+
int[][] lcp = new int[n + 1][n + 1];
118+
119+
for (int i = n - 1; i >= 0; i--) {
120+
for (int j = n - 1; j > i; j--) {
121+
if (nums[i] == nums[j]) {
122+
lcp[i][j] = lcp[i + 1][j + 1] + 1;
123+
}
124+
}
125+
}
126+
127+
int ans = 0;
128+
for (int i = 1; i < n - 1; i++) {
129+
for (int j = i + 1; j < n; j++) {
130+
boolean a = (i <= j - i) && (lcp[0][i] >= i);
131+
boolean b = (j - i <= n - j) && (lcp[i][j] >= j - i);
132+
if (a || b) {
133+
ans++;
134+
}
135+
}
136+
}
137+
138+
return ans;
139+
}
140+
}
91141
```
92142

93143
#### C++
94144

95145
```cpp
96-
146+
class Solution {
147+
public:
148+
int beautifulSplits(vector<int>& nums) {
149+
int n = nums.size();
150+
vector<vector<int>> lcp(n + 1, vector<int>(n + 1, 0));
151+
152+
for (int i = n - 1; i >= 0; i--) {
153+
for (int j = n - 1; j > i; j--) {
154+
if (nums[i] == nums[j]) {
155+
lcp[i][j] = lcp[i + 1][j + 1] + 1;
156+
}
157+
}
158+
}
159+
160+
int ans = 0;
161+
for (int i = 1; i < n - 1; i++) {
162+
for (int j = i + 1; j < n; j++) {
163+
bool a = (i <= j - i) && (lcp[0][i] >= i);
164+
bool b = (j - i <= n - j) && (lcp[i][j] >= j - i);
165+
if (a || b) {
166+
ans++;
167+
}
168+
}
169+
}
170+
171+
return ans;
172+
}
173+
};
97174
```
98175

99176
#### Go
100177

101178
```go
179+
func beautifulSplits(nums []int) (ans int) {
180+
n := len(nums)
181+
lcp := make([][]int, n+1)
182+
for i := range lcp {
183+
lcp[i] = make([]int, n+1)
184+
}
185+
186+
for i := n - 1; i >= 0; i-- {
187+
for j := n - 1; j > i; j-- {
188+
if nums[i] == nums[j] {
189+
lcp[i][j] = lcp[i+1][j+1] + 1
190+
}
191+
}
192+
}
193+
194+
for i := 1; i < n-1; i++ {
195+
for j := i + 1; j < n; j++ {
196+
a := i <= j-i && lcp[0][i] >= i
197+
b := j-i <= n-j && lcp[i][j] >= j-i
198+
if a || b {
199+
ans++
200+
}
201+
}
202+
}
203+
204+
return
205+
}
206+
```
102207

208+
#### TypeScript
209+
210+
```ts
211+
function beautifulSplits(nums: number[]): number {
212+
const n = nums.length;
213+
const lcp: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
214+
215+
for (let i = n - 1; i >= 0; i--) {
216+
for (let j = n - 1; j > i; j--) {
217+
if (nums[i] === nums[j]) {
218+
lcp[i][j] = lcp[i + 1][j + 1] + 1;
219+
}
220+
}
221+
}
222+
223+
let ans = 0;
224+
for (let i = 1; i < n - 1; i++) {
225+
for (let j = i + 1; j < n; j++) {
226+
const a = i <= j - i && lcp[0][i] >= i;
227+
const b = j - i <= n - j && lcp[i][j] >= j - i;
228+
if (a || b) {
229+
ans++;
230+
}
231+
}
232+
}
233+
234+
return ans;
235+
}
103236
```
104237

105238
<!-- tabs:end -->
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution {
2+
public:
3+
int beautifulSplits(vector<int>& nums) {
4+
int n = nums.size();
5+
vector<vector<int>> lcp(n + 1, vector<int>(n + 1, 0));
6+
7+
for (int i = n - 1; i >= 0; i--) {
8+
for (int j = n - 1; j > i; j--) {
9+
if (nums[i] == nums[j]) {
10+
lcp[i][j] = lcp[i + 1][j + 1] + 1;
11+
}
12+
}
13+
}
14+
15+
int ans = 0;
16+
for (int i = 1; i < n - 1; i++) {
17+
for (int j = i + 1; j < n; j++) {
18+
bool a = (i <= j - i) && (lcp[0][i] >= i);
19+
bool b = (j - i <= n - j) && (lcp[i][j] >= j - i);
20+
if (a || b) {
21+
ans++;
22+
}
23+
}
24+
}
25+
26+
return ans;
27+
}
28+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
func beautifulSplits(nums []int) (ans int) {
2+
n := len(nums)
3+
lcp := make([][]int, n+1)
4+
for i := range lcp {
5+
lcp[i] = make([]int, n+1)
6+
}
7+
8+
for i := n - 1; i >= 0; i-- {
9+
for j := n - 1; j > i; j-- {
10+
if nums[i] == nums[j] {
11+
lcp[i][j] = lcp[i+1][j+1] + 1
12+
}
13+
}
14+
}
15+
16+
for i := 1; i < n-1; i++ {
17+
for j := i + 1; j < n; j++ {
18+
a := i <= j-i && lcp[0][i] >= i
19+
b := j-i <= n-j && lcp[i][j] >= j-i
20+
if a || b {
21+
ans++
22+
}
23+
}
24+
}
25+
26+
return
27+
}

0 commit comments

Comments
(0)

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