25.7.16 25.7.17 每日一题——找出有效子序列的最大长度 I/II
Description
定义有效子序列 sub=sub=sub=
(sub[0]+sub[1])modk=(sub[1]+sub[2])modk=...=(sub[n−2]+sub[n−1])modk(sub[0] + sub[1]) \mod k = (sub[1] + sub[2]) \mod k = ... = (sub[n - 2] + sub[n - 1]) \mod k(sub[0]+sub[1])modk=(sub[1]+sub[2])modk=...=(sub[n−2]+sub[n−1])modk
(nnn 为长度)
让我们最大化 nnn。
Solution
对于等式
(a+b)modm=(b+c)modk(a+b) \mod m=(b+c) \mod k(a+b)modm=(b+c)modk
移项,得
(a+b−(b+c))modk=0(a+b−(b+c)) \mod k=0(a+b−(b+c))modk=0
化简得
(a−c)modk=0(a−c) \mod k=0(a−c)modk=0
这意味着 aaa 与 ccc 模 kkk 同余。即题目式子中的 sub[i]sub[i]sub[i] 与 sub[i+2]sub[i+2]sub[i+2] 模 kkk 同余。
如果把每个 nums[i]nums[i]nums[i] 都改成 nums[i]modknums[i] \mod knums[i]modk,问题等价于:
- 求最长子序列的长度,该子序列的奇数项都相同,偶数项都相同。
如果确定了子序列的最后两项,就确定了整个子序列。
那么我们可以从左到右遍历 numsnumsnums,遍历的同时,维护一个二维数组 f[y][x]f[y][x]f[y][x],表示最后两项模 kkk 分别为 yyy 和 xxx 的子序列的长度。
对于 x=nums[i]modkx=nums[i] \mod kx=nums[i]modk,我们可以在最后两项模 kkk 分别为 xxx 和 yyy 的子序列的末尾添加 nums[i]nums[i]nums[i],那么最后两项模 kkk 分别为 yyy 和 xxx 的子序列的长度会增加 1,即
f[y][x]=f[x][y]+1f[y][x]=f[x][y]+1f[y][x]=f[x][y]+1
最后答案为 fff 中的最大值。
(其中有些讲解取自大神灵茶山艾府,感谢他)
昨天的题就是 k=2k=2k=2的情况,直接cv就行……
Code1(C++、Python3)
C++
class Solution {
public:int maximumLength(vector<int>& nums) {int ans = 0;vector f(2, vector<int>(2));for (int x : nums) {x %= 2;for (int y = 0; y < 2; y++) {f[y][x] = f[x][y] + 1;ans = max(ans, f[y][x]);}}return ans;}
};
Python3
class Solution:def maximumLength(self, nums: List[int]) -> int:ans = 0f = [[0] * 2 for _ in range(2)]for x in nums:x %= 2for y in range(2):f[y][x] = f[x][y] + 1ans = max(ans, f[y][x])return ans
Code2(C++、Python3)
C++
class Solution {
public:int maximumLength(vector<int>& nums, int k) {int ans = 0;vector f(k, vector<int>(k));for (int x : nums) {x %= k;for (int y = 0; y < k; y++) {f[y][x] = f[x][y] + 1;ans = max(ans, f[y][x]);}}return ans;}
};
Python3
class Solution:def maximumLength(self, nums: List[int], k: int) -> int:ans = 0f = [[0] * k for _ in range(k)]for x in nums:x %= kfor y in range(k):f[y][x] = f[x][y] + 1ans = max(ans, f[y][x])return ans
欢迎大家关注LeetCode——C2h6oqwq。也恳求大家点赞收藏加关注~~~