跳到主要内容

Leetcode: 2369. 检查数组是否存在有效划分

题目

https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/description/

代码

/*
* @lc app=leetcode.cn id=2369 lang=cpp
*
* [2369] 检查数组是否存在有效划分
*/

#include <csignal>
#include <cstddef>
#include <vector>
using namespace std;
// @lc code=start
class Solution {
bool dfs(const vector<int> &nums, int n) {
// 如果刚好分配完
if (n == -1) return true;
// 如果仅剩一个数, 或者非法 n
if (n <= 0) return false;

/*
在后两个数相等的情况下看前n-2个数是否满足
在后三个数相等的情况下看前n-3个数是否满足
在后三个数连续的情况下看前n-3各数是否满足
*/
if (nums[n] == nums[n - 1]) {
bool ok = dfs(nums, n - 2);

if (!ok && nums[n - 1] == nums[n - 2]) {
ok = dfs(nums, n - 3);
}
return ok;
}

if (n >= 2 && nums[n] == nums[n - 1] + 1 &&
nums[n] == nums[n - 2] + 2) {
return dfs(nums, n - 3);
}

// 既不相等又不连续
return false;
}

// 会超时
bool dfs2(const vector<int> &nums, int n) {
// 如果刚好分配完
if (n == -1) return true;
// 如果仅剩一个数, 或者非法 n
if (n <= 0) return false;

/*
在前n-2个数满足的情况下看后两个数是否相等
在前n-3各数满足的情况下看后三个数是否相等或者连续
*/
if (dfs2(nums, n - 2)) {
if (nums[n] == nums[n - 1]) {
return true;
}
}

if (n >= 2 && dfs2(nums, n - 3)) {
if ((nums[n] == nums[n - 1] && nums[n] == nums[n - 2]) ||
(nums[n] == nums[n - 1] + 1 && nums[n] == nums[n - 2] + 2)) {
return true;
}
}

// 前n-2或前n-3都不满足,
// 或者后两个不相等,或这后三个不相等,或后三个不连续
return false;
}

// 动态规划, 参照dfs2
bool solve(const vector<int> &nums) {
const int n = nums.size();
vector<bool> f(n + 1, false);
f[0] = true;
// f[i] 代表是否能划分 nums[0, i)
// 即f[n] 代表 nums[0, n);
for (int i = 1; i < n; ++i) {
if (f[i - 2 + 1]) {
f[i + 1] = nums[i] == nums[i - 1];
}
if (i >= 2 && f[i - 3 + 1]) {
f[i + 1] =
f[i + 1] ||
(nums[i] == nums[i - 1] && nums[i] == nums[i - 2]) ||
(nums[i] == nums[i - 1] + 1 && nums[i] == nums[i - 2] + 2);
}
}

return f[n];
}

public:
bool validPartition(vector<int> &nums) {
// return dfs(nums, nums.size() - 1);
// return dfs2(nums, nums.size() - 1);
return solve(nums);
};
};
// @lc code=end