Skip to content

Files

Latest commit

7840036 · Jul 24, 2024

History

History

3201.Find the Maximum Length of Valid Subsequence I

comments difficulty edit_url rating source tags
true
中等
1663
第 404 场周赛 Q2
数组
动态规划

English Version

题目描述

给你一个整数数组 nums

nums 的子序列 sub 的长度为 x ,如果其满足以下条件,则称其为 有效子序列

  • (sub[0] + sub[1]) % 2 == (sub[1] + sub[2]) % 2 == ... == (sub[x - 2] + sub[x - 1]) % 2

返回 nums最长的有效子序列 的长度。

一个 子序列 指的是从原数组中删除一些元素(也可以不删除任何元素),剩余元素保持原来顺序组成的新数组。

 

示例 1:

输入: nums = [1,2,3,4]

输出: 4

解释:

最长的有效子序列是 [1, 2, 3, 4]

示例 2:

输入: nums = [1,2,1,1,2,1,2]

输出: 6

解释:

最长的有效子序列是 [1, 2, 1, 2, 1, 2]

示例 3:

输入: nums = [1,3]

输出: 2

解释:

最长的有效子序列是 [1, 3]

 

提示:

  • 2 <= nums.length <= 2 * 105
  • 1 <= nums[i] <= 107

解法

方法一:动态规划

我们令 k = 2

根据题目描述,我们可以得知,对于子序列 a 1 , a 2 , a 3 , , a x ,如果满足 ( a 1 + a 2 ) mod k = ( a 2 + a 3 ) mod k 。那么 a 1 mod k = a 3 mod k 。也即是说,所有奇数项元素对 k 取模的结果相同,所有偶数项元素对 k 取模的结果相同。

我们可以使用动态规划的方法解决这个问题。定义状态 f [ x ] [ y ] 表示最后一项对 k 取模为 x ,倒数第二项对 k 取模为 y 的最长有效子序列的长度。初始时 f [ x ] [ y ] = 0

遍历数组 n u m s ,对于每一个数 x ,我们得到 x = x mod k 。然后我们可以枚举序列连续两个数对 j 取模结果相同,其中 j [ 0 , k ) 。那么 x 的前一个数对 k 取模结果为 y = ( j x + k ) mod k 。此时 f [ x ] [ y ] = f [ y ] [ x ] + 1

答案为所有 f [ x ] [ y ] 中的最大值。

时间复杂度 O ( n × k ) ,空间复杂度 O ( k 2 ) 。其中 n 为数组 nums 的长度,而 k = 2

Python3

class Solution:
    def maximumLength(self, nums: List[int]) -> int:
        k = 2
        f = [[0] * k for _ in range(k)]
        ans = 0
        for x in nums:
            x %= k
            for j in range(k):
                y = (j - x + k) % k
                f[x][y] = f[y][x] + 1
                ans = max(ans, f[x][y])
        return ans

Java

class Solution {
    public int maximumLength(int[] nums) {
        int k = 2;
        int[][] f = new int[k][k];
        int ans = 0;
        for (int x : nums) {
            x %= k;
            for (int j = 0; j < k; ++j) {
                int y = (j - x + k) % k;
                f[x][y] = f[y][x] + 1;
                ans = Math.max(ans, f[x][y]);
            }
        }
        return ans;
    }
}

C++

class Solution {
public:
    int maximumLength(vector<int>& nums) {
        int k = 2;
        int f[k][k];
        memset(f, 0, sizeof(f));
        int ans = 0;
        for (int x : nums) {
            x %= k;
            for (int j = 0; j < k; ++j) {
                int y = (j - x + k) % k;
                f[x][y] = f[y][x] + 1;
                ans = max(ans, f[x][y]);
            }
        }
        return ans;
    }
};

Go

func maximumLength(nums []int) (ans int) {
	k := 2
	f := make([][]int, k)
	for i := range f {
		f[i] = make([]int, k)
	}
	for _, x := range nums {
		x %= k
		for j := 0; j < k; j++ {
			y := (j - x + k) % k
			f[x][y] = f[y][x] + 1
			ans = max(ans, f[x][y])
		}
	}
	return
}

TypeScript

function maximumLength(nums: number[]): number {
    const k = 2;
    const f: number[][] = Array.from({ length: k }, () => Array(k).fill(0));
    let ans: number = 0;
    for (let x of nums) {
        x %= k;
        for (let j = 0; j < k; ++j) {
            const y = (j - x + k) % k;
            f[x][y] = f[y][x] + 1;
            ans = Math.max(ans, f[x][y]);
        }
    }
    return ans;
}