3202. Find the Maximum Length of Valid Subsequence II

Dare2Solve

Dare2Solve

3202. Find the Maximum Length of Valid Subsequence II
SAMSUNG 49-Inch Odyssey G9
SAMSUNG 49-Inch Odyssey G9
Because earth is not flat

Intuition

To solve the problem of finding the longest valid subsequence where consecutive pairs have equal sums modulo k, we can utilize a dynamic programming approach. The key insight is to maintain a mapping of remainder values modulo k to the length of subsequences that end with each remainder.

Approach

  1. Initialization: Initialize a dictionary or array remainder_to_length to keep track of the maximum length of subsequences that end with each remainder modulo k.

  2. Iterate through nums: For each number num in nums, calculate its remainder modulo k.

  3. Update lengths: For each remainder, update remainder_to_length by considering adding num to subsequences ending with the previous remainder (curr_remainder + num) % k.

  4. Track maximum length: Maintain a variable max_length to store the maximum length found during the iteration.

  5. Return result: After iterating through all numbers in nums, max_length will contain the length of the longest valid subsequence.

Complexity

The solution efficiently computes the length of the longest valid subsequence using dynamic programming and hashing, ensuring optimal performance.

Code Explanation

var maximumLength = function (nums, k) {
let dp = new Array(k * k).fill(0);
var helper = (x, y) => x * k + y;
nums.forEach((num) => {
  num %= k;
  for (let i = 0; i < k; i++) {
    if (dp[helper(num, i)] + 1 > dp[helper(i, num)]) {
      dp[helper(i, num)] = dp[helper(num, i)] + 1;
    }
  }
});
  return Math.max(...dp);
};

Code

C++

class Solution {
public:
    int maximumLength(vector<int>& nums, int k) {
        vector<int> dp(k * k, 0);
        
        auto helper = [&](int x, int y, int k) {
            return x * k + y;
        };
        
        for (int num : nums) {
            num %= k;
            for (int i = 0; i < k; i++) {
                if (dp[helper(num, i, k)] + 1 > dp[helper(i, num, k)]) {
                    dp[helper(i, num, k)] = dp[helper(num, i, k)] + 1;
                }
            }
        }
        
        return *max_element(dp.begin(), dp.end());
    }
};

Python

class Solution:
    def maximumLength(self, nums: List[int], k: int) -> int:
        dp = [0] * (k * k)
        
        def helper(x, y, k):
            return x * k + y
        
        for num in nums:
            num %= k
            for i in range(k):
                if dp[helper(num, i, k)] + 1 > dp[helper(i, num, k)]:
                    dp[helper(i, num, k)] = dp[helper(num, i, k)] + 1
        
        return max(dp)

Java

class Solution {
    public int maximumLength(int[] nums, int k) {
        int[] dp = new int[k * k];
        
        for (int num : nums) {
            num %= k;
            for (int i = 0; i < k; i++) {
                if (dp[helper(num, i, k)] + 1 > dp[helper(i, num, k)]) {
                    dp[helper(i, num, k)] = dp[helper(num, i, k)] + 1;
                }
            }
        }
        
        int max = 0;
        for (int value : dp) {
            max = Math.max(max, value);
        }
        
        return max;
    }
    
    private int helper(int x, int y, int k) {
        return x * k + y;
    }
}

JavaScript

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var maximumLength = function (nums, k) {
  let dp = new Array(k * k).fill(0);
  var helper = (x, y) => x * k + y;

  nums.forEach((num) => {
    num %= k;
    for (let i = 0; i < k; i++) {
      if (dp[helper(num, i)] + 1 > dp[helper(i, num)]) {
        dp[helper(i, num)] = dp[helper(num, i)] + 1;
      }
    }
  });

  return Math.max(...dp);
};