【LetMeFly】3202.找出有效子序列的最大长度 II:取模性质(动态规划)
力扣题目链接:https://leetcode.cn/problems/find-the-maximum-length-of-valid-subsequence-ii/
给你一个整数数组 nums
和一个 正 整数 k
。
nums
的一个 子序列 sub
的长度为 x
,如果其满足以下条件,则称其为 有效子序列 :
(sub[0] + sub[1]) % k == (sub[1] + sub[2]) % k == ... == (sub[x - 2] + sub[x - 1]) % k
返回 nums
的 最长 有效子序列 的长度。
示例 1:
**输入:**nums = [1,2,3,4,5], k = 2
**输出:**5
解释:
最长有效子序列是 [1, 2, 3, 4, 5]
。
示例 2:
**输入:**nums = [1,4,2,3,1,4], k = 3
**输出:**4
解释:
最长有效子序列是 [1, 4, 1, 4]
。
提示:
2 <= nums.length <= 10
31 <= nums[i] <= 10
71 <= k <= 10
3
解题方法:动态规划(DP)
一个序列 [ a 1 , b 1 , a 2 , b 2 , a 3 , ... ] [a_1,b_1,a_2,b_2,a_3,\dots] [a1,b1,a2,b2,a3,...]满足 ( a 1 + b 1 ) % k = = ( b 1 + a 2 ) % k = = ( a 2 + b 2 ) % k = = ... (a_1+b_1)\% k == (b_1+a_2)\%k == (a_2+b2)\%k==\dots (a1+b1)%k==(b1+a2)%k==(a2+b2)%k==...的话,则有:
a 1 , a 2 , ... a_1, a_2,\dots a1,a2,...对 k k k同余, b 1 , b 2 , ... b_1,b_2,\dots b1,b2,...对 k k k同余。
所谓同余,就是模 k k k后的结果相等。
使用一个动态规划数组 d p [ i ] [ j ] dp[i][j] dp[i][j]代表 a ∗ a_* a∗模 k k k等于 i i i而 b ∗ b_* b∗模 k k k等于 j j j的 [ a 1 , b 1 , a 2 , b 2 ... ] [a_1,b_1,a_2,b_2\dots] [a1,b1,a2,b2...]序列的最大长度,则可以:
遍历 n u m s nums nums数组,若当前元素(对 k k k取模后)为 x x x,则任何 y x y x yxyx yxyx序列的长度都可以在 x y x y xyxy xyxy序列的基础上再加一个 x x x从而变成 y x y x yxyx yxyx序列。
d p [ y ] [ x ] = d p [ x ] [ y ] + 1 dp[y][x]=dp[x][y]+1 dp[y][x]=dp[x][y]+1
注意, d p [ a ] [ b ] dp[a][b] dp[a][b]代表的 a b a b abab abab序列,结尾一定是 b b b,但开头不一定是 a a a(可以是 a b a b abab abab也可以是 b a b a b babab babab)。
- 时间复杂度 O ( O( O(k^2+nk ) ) )
- 空间复杂度 O ( k 2 ) O(k^2) O(k2)
AC代码
C++
cpp
/*
* @Author: LetMeFly
* @Date: 2025-07-18 22:33:22
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-07-20 19:32:05
*/
#if defined(_WIN32) || defined(__APPLE__)
#include "_[1,2]toVector.h"
#endif
class Solution {
public:
int maximumLength(vector<int>& nums, int k) {
vector<vector<int>> dp(k, vector<int>(k));
int ans = 0;
for (int x : nums) {
x %= k;
for (int y = 0; y < k; y++) {
dp[y][x] = dp[x][y] + 1;
ans = max(ans, dp[y][x]);
}
}
return ans;
}
};
Python
python
'''
Author: LetMeFly
Date: 2025-07-18 22:33:22
LastEditors: LetMeFly.xyz
LastEditTime: 2025-07-20 22:23:43
'''
from typing import List
class Solution:
def maximumLength(self, nums: List[int], k: int) -> int:
dp = [[0] * k for _ in range(k)]
for x in nums:
x %= k
for y in range(k):
dp[y][x] = dp[x][y] + 1
return max(map(max, dp))
Go
go
/*
* @Author: LetMeFly
* @Date: 2025-07-18 22:33:22
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-07-20 22:28:07
*/
package main
func maximumLength(nums []int, k int) (ans int) {
dp := make([][]int, k)
for i := range dp {
dp[i] = make([]int, k)
}
for _, x := range nums {
x %= k
for y := range dp {
dp[y][x] = dp[x][y] + 1
ans = max(ans, dp[y][x])
}
}
return
}
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源