comments | difficulty | edit_url | tags | ||
---|---|---|---|---|---|
true |
中等 |
|
给你一个整数数组 nums
。
如果数组 nums
的一个分割满足以下条件,我们称它是一个 美丽 分割:
- 数组
nums
分为三段 非空子数组:nums1
,nums2
和nums3
,三个数组nums1
,nums2
和nums3
按顺序连接可以得到nums
。 - 子数组
nums1
是子数组nums2
的 前缀 或者nums2
是nums3
的 前缀。
请你返回满足以上条件的分割 数目 。
子数组 指的是一个数组里一段连续 非空 的元素。
前缀 指的是一个数组从头开始到中间某个元素结束的子数组。
示例 1:
输入:nums = [1,1,2,1]
输出:2
解释:
美丽分割如下:
nums1 = [1]
,nums2 = [1,2]
,nums3 = [1]
。nums1 = [1]
,nums2 = [1]
,nums3 = [2,1]
。
示例 2:
输入:nums = [1,2,3,4]
输出:0
解释:
没有美丽分割。
提示:
1 <= nums.length <= 5000
0 <= nums[i] <= 50
我们可以预处理
接下来,我们倒序枚举
最后,我们枚举第一个子数组的结尾位置
枚举结束后,答案即为美丽的分割数目。
时间复杂度
class Solution:
def beautifulSplits(self, nums: List[int]) -> int:
n = len(nums)
lcp = [[0] * (n + 1) for _ in range(n + 1)]
for i in range(n - 1, -1, -1):
for j in range(n - 1, i - 1, -1):
if nums[i] == nums[j]:
lcp[i][j] = lcp[i + 1][j + 1] + 1
ans = 0
for i in range(1, n - 1):
for j in range(i + 1, n):
a = i <= j - i and lcp[0][i] >= i
b = j - i <= n - j and lcp[i][j] >= j - i
ans += int(a or b)
return ans
class Solution {
public int beautifulSplits(int[] nums) {
int n = nums.length;
int[][] lcp = new int[n + 1][n + 1];
for (int i = n - 1; i >= 0; i--) {
for (int j = n - 1; j > i; j--) {
if (nums[i] == nums[j]) {
lcp[i][j] = lcp[i + 1][j + 1] + 1;
}
}
}
int ans = 0;
for (int i = 1; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
boolean a = (i <= j - i) && (lcp[0][i] >= i);
boolean b = (j - i <= n - j) && (lcp[i][j] >= j - i);
if (a || b) {
ans++;
}
}
}
return ans;
}
}
class Solution {
public:
int beautifulSplits(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> lcp(n + 1, vector<int>(n + 1, 0));
for (int i = n - 1; i >= 0; i--) {
for (int j = n - 1; j > i; j--) {
if (nums[i] == nums[j]) {
lcp[i][j] = lcp[i + 1][j + 1] + 1;
}
}
}
int ans = 0;
for (int i = 1; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
bool a = (i <= j - i) && (lcp[0][i] >= i);
bool b = (j - i <= n - j) && (lcp[i][j] >= j - i);
if (a || b) {
ans++;
}
}
}
return ans;
}
};
func beautifulSplits(nums []int) (ans int) {
n := len(nums)
lcp := make([][]int, n+1)
for i := range lcp {
lcp[i] = make([]int, n+1)
}
for i := n - 1; i >= 0; i-- {
for j := n - 1; j > i; j-- {
if nums[i] == nums[j] {
lcp[i][j] = lcp[i+1][j+1] + 1
}
}
}
for i := 1; i < n-1; i++ {
for j := i + 1; j < n; j++ {
a := i <= j-i && lcp[0][i] >= i
b := j-i <= n-j && lcp[i][j] >= j-i
if a || b {
ans++
}
}
}
return
}
function beautifulSplits(nums: number[]): number {
const n = nums.length;
const lcp: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
for (let i = n - 1; i >= 0; i--) {
for (let j = n - 1; j > i; j--) {
if (nums[i] === nums[j]) {
lcp[i][j] = lcp[i + 1][j + 1] + 1;
}
}
}
let ans = 0;
for (let i = 1; i < n - 1; i++) {
for (let j = i + 1; j < n; j++) {
const a = i <= j - i && lcp[0][i] >= i;
const b = j - i <= n - j && lcp[i][j] >= j - i;
if (a || b) {
ans++;
}
}
}
return ans;
}