Greatest Sum Divisible by Three

medium dynamic programming modular arithmetic array

Problem

Given an integer array nums, return the maximum possible sum of a subset of its elements such that the sum is divisible by three. You may pick any subset (including the empty one, whose sum is 0).

Inputnums = [3,6,5,1,8]
Output18
Pick 3, 6, 1 and 8 — their sum 18 is the largest total divisible by 3.
Inputnums = [1,2,3,4,4]
Output12
Pick 1, 3, 4 and 4 — their sum is 12, the maximum divisible by 3.

def max_sum_div_three(nums):
    NEG = float("-inf")
    dp = [0, NEG, NEG]          # dp[r] = best sum with sum % 3 == r
    for v in nums:
        cur = dp[:]             # snapshot before using v
        for r in range(3):
            if cur[r] == NEG:
                continue
            nr = (cur[r] + v) % 3
            dp[nr] = max(dp[nr], cur[r] + v)
    return dp[0]
function maxSumDivThree(nums) {
  const NEG = -Infinity;
  let dp = [0, NEG, NEG];        // dp[r] = best sum with sum % 3 === r
  for (const v of nums) {
    const cur = dp.slice();      // snapshot before using v
    for (let r = 0; r < 3; r++) {
      if (cur[r] === NEG) continue;
      const nr = (cur[r] + v) % 3;
      dp[nr] = Math.max(dp[nr], cur[r] + v);
    }
  }
  return dp[0];
}
int maxSumDivThree(int[] nums) {
    final int NEG = Integer.MIN_VALUE;
    int[] dp = {0, NEG, NEG};      // dp[r] = best sum with sum % 3 == r
    for (int v : nums) {
        int[] cur = dp.clone();    // snapshot before using v
        for (int r = 0; r < 3; r++) {
            if (cur[r] == NEG) continue;
            int nr = (cur[r] + v) % 3;
            dp[nr] = Math.max(dp[nr], cur[r] + v);
        }
    }
    return dp[0];
}
int maxSumDivThree(vector<int>& nums) {
    const int NEG = INT_MIN;
    vector<int> dp = {0, NEG, NEG};   // dp[r] = best sum, sum % 3 == r
    for (int v : nums) {
        vector<int> cur = dp;         // snapshot before using v
        for (int r = 0; r < 3; r++) {
            if (cur[r] == NEG) continue;
            int nr = (cur[r] + v) % 3;
            dp[nr] = max(dp[nr], cur[r] + v);
        }
    }
    return dp[0];
}
Time: O(n) Space: O(1)