comments | difficulty | edit_url | rating | source | tags | |||
---|---|---|---|---|---|---|---|---|
true |
困难 |
2364 |
第 132 场双周赛 Q4 |
|
给你一个整数数组 nums
和一个 非负 整数 k
。如果一个整数序列 seq
满足在范围下标范围 [0, seq.length - 2]
中存在 不超过 k
个下标 i
满足 seq[i] != seq[i + 1]
,那么我们称这个整数序列为 好 序列。
请你返回 nums
中 好 子序列 的最长长度
示例 1:
输入:nums = [1,2,1,1,3], k = 2
输出:4
解释:
最长好子序列为 [1,2,1,1,3]
。
示例 2:
输入:nums = [1,2,3,4,5,1], k = 0
输出:2
解释:
最长好子序列为 [1,2,3,4,5,1]
。
提示:
1 <= nums.length <= 5 * 103
1 <= nums[i] <= 109
0 <= k <= min(50, nums.length)
我们定义
我们考虑如何计算
最终答案为
时间复杂度 nums
的长度。
由于本题数据范围较大,上述解法会超时,需要进行优化。
根据状态转移方程,如果
时间复杂度 nums
的长度。
class Solution:
def maximumLength(self, nums: List[int], k: int) -> int:
n = len(nums)
f = [[0] * (k + 1) for _ in range(n)]
mp = [defaultdict(int) for _ in range(k + 1)]
g = [[0] * 3 for _ in range(k + 1)]
ans = 0
for i, x in enumerate(nums):
for h in range(k + 1):
f[i][h] = mp[h][x]
if h:
if g[h - 1][0] != nums[i]:
f[i][h] = max(f[i][h], g[h - 1][1])
else:
f[i][h] = max(f[i][h], g[h - 1][2])
f[i][h] += 1
mp[h][nums[i]] = max(mp[h][nums[i]], f[i][h])
if g[h][0] != x:
if f[i][h] >= g[h][1]:
g[h][2] = g[h][1]
g[h][1] = f[i][h]
g[h][0] = x
else:
g[h][2] = max(g[h][2], f[i][h])
else:
g[h][1] = max(g[h][1], f[i][h])
ans = max(ans, f[i][h])
return ans
class Solution {
public int maximumLength(int[] nums, int k) {
int n = nums.length;
int[][] f = new int[n][k + 1];
Map<Integer, Integer>[] mp = new HashMap[k + 1];
Arrays.setAll(mp, i -> new HashMap<>());
int[][] g = new int[k + 1][3];
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int h = 0; h <= k; ++h) {
f[i][h] = mp[h].getOrDefault(nums[i], 0);
if (h > 0) {
if (g[h - 1][0] != nums[i]) {
f[i][h] = Math.max(f[i][h], g[h - 1][1]);
} else {
f[i][h] = Math.max(f[i][h], g[h - 1][2]);
}
}
++f[i][h];
mp[h].merge(nums[i], f[i][h], Integer::max);
if (g[h][0] != nums[i]) {
if (f[i][h] >= g[h][1]) {
g[h][2] = g[h][1];
g[h][1] = f[i][h];
g[h][0] = nums[i];
} else {
g[h][2] = Math.max(g[h][2], f[i][h]);
}
} else {
g[h][1] = Math.max(g[h][1], f[i][h]);
}
ans = Math.max(ans, f[i][h]);
}
}
return ans;
}
}
class Solution {
public:
int maximumLength(vector<int>& nums, int k) {
int n = nums.size();
vector<vector<int>> f(n, vector<int>(k + 1));
vector<unordered_map<int, int>> mp(k + 1);
vector<vector<int>> g(k + 1, vector<int>(3));
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int h = 0; h <= k; ++h) {
f[i][h] = mp[h][nums[i]];
if (h > 0) {
if (g[h - 1][0] != nums[i]) {
f[i][h] = max(f[i][h], g[h - 1][1]);
} else {
f[i][h] = max(f[i][h], g[h - 1][2]);
}
}
++f[i][h];
mp[h][nums[i]] = max(mp[h][nums[i]], f[i][h]);
if (g[h][0] != nums[i]) {
if (f[i][h] >= g[h][1]) {
g[h][2] = g[h][1];
g[h][1] = f[i][h];
g[h][0] = nums[i];
} else {
g[h][2] = max(g[h][2], f[i][h]);
}
} else {
g[h][1] = max(g[h][1], f[i][h]);
}
ans = max(ans, f[i][h]);
}
}
return ans;
}
};
func maximumLength(nums []int, k int) int {
n := len(nums)
f := make([][]int, n)
for i := range f {
f[i] = make([]int, k+1)
}
mp := make([]map[int]int, k+1)
for i := range mp {
mp[i] = make(map[int]int)
}
g := make([][3]int, k+1)
ans := 0
for i := 0; i < n; i++ {
for h := 0; h <= k; h++ {
f[i][h] = mp[h][nums[i]]
if h > 0 {
if g[h-1][0] != nums[i] {
if g[h-1][1] > f[i][h] {
f[i][h] = g[h-1][1]
}
} else {
if g[h-1][2] > f[i][h] {
f[i][h] = g[h-1][2]
}
}
}
f[i][h]++
if f[i][h] > mp[h][nums[i]] {
mp[h][nums[i]] = f[i][h]
}
if g[h][0] != nums[i] {
if f[i][h] >= g[h][1] {
g[h][2] = g[h][1]
g[h][1] = f[i][h]
g[h][0] = nums[i]
} else if f[i][h] > g[h][2] {
g[h][2] = f[i][h]
}
} else {
if f[i][h] > g[h][1] {
g[h][1] = f[i][h]
}
}
if f[i][h] > ans {
ans = f[i][h]
}
}
}
return ans
}
function maximumLength(nums: number[], k: number): number {
const n = nums.length;
const f: number[][] = Array.from({ length: n }, () => Array(k + 1).fill(0));
const mp: Map<number, number>[] = Array.from({ length: k + 1 }, () => new Map());
const g: number[][] = Array.from({ length: k + 1 }, () => Array(3).fill(0));
let ans = 0;
for (let i = 0; i < n; i++) {
for (let h = 0; h <= k; h++) {
f[i][h] = mp[h].get(nums[i]) || 0;
if (h > 0) {
if (g[h - 1][0] !== nums[i]) {
f[i][h] = Math.max(f[i][h], g[h - 1][1]);
} else {
f[i][h] = Math.max(f[i][h], g[h - 1][2]);
}
}
f[i][h]++;
mp[h].set(nums[i], Math.max(mp[h].get(nums[i]) || 0, f[i][h]));
if (g[h][0] !== nums[i]) {
if (f[i][h] >= g[h][1]) {
g[h][2] = g[h][1];
g[h][1] = f[i][h];
g[h][0] = nums[i];
} else {
g[h][2] = Math.max(g[h][2], f[i][h]);
}
} else {
g[h][1] = Math.max(g[h][1], f[i][h]);
}
ans = Math.max(ans, f[i][h]);
}
}
return ans;
}