2342. Max Sum of a Pair With Equal Sum of Digits
Problem Description
You have an array nums
containing positive integers, and you need to find two different elements whose digit sums are equal, then return their maximum possible sum.
Here's what you need to do:
- Pick two different indices
i
andj
(wherei != j
) - Calculate the sum of digits for
nums[i]
andnums[j]
- If these digit sums are equal, consider the sum
nums[i] + nums[j]
- Return the maximum such sum across all valid pairs
The digit sum means adding up all individual digits of a number. For example:
- The digit sum of
243
is2 + 4 + 3 = 9
- The digit sum of
81
is8 + 1 = 9
If you can't find any two numbers with equal digit sums, return -1
.
Example scenarios:
- If
nums = [18, 43, 36, 13, 7]
:18
has digit sum1 + 8 = 9
36
has digit sum3 + 6 = 9
- These two numbers have equal digit sums, so we can pair them:
18 + 36 = 54
43
has digit sum4 + 3 = 7
7
has digit sum7
- These also match, giving us:
43 + 7 = 50
- The maximum is
54
The goal is to find the largest possible sum among all valid pairs with matching digit sums.
Intuition
When looking for pairs with equal digit sums, we need to group numbers by their digit sum. The key insight is that we don't need to track all numbers with the same digit sum - we only need to track the maximum value for each digit sum group.
Why? Because to maximize nums[i] + nums[j]
where both have the same digit sum, we want the two largest numbers from that group.
Think of it this way: if we have three numbers [18, 36, 45]
all with digit sum 9
, the maximum pair sum would be 36 + 45 = 81
. We don't need to consider 18
once we've seen larger numbers with the same digit sum.
This leads to a greedy strategy:
- As we traverse the array, we calculate each number's digit sum
- For each digit sum, we maintain only the largest number we've seen so far
- When we encounter a new number with a digit sum we've seen before, we can immediately calculate a potential answer by adding it to the previously stored maximum
- Then we update our stored maximum if the current number is larger
This single-pass approach works because:
- When we see the second number with a particular digit sum, we form a pair with the first (which is the only one available)
- When we see the third or later numbers with that digit sum, we always pair with the largest previous one
- We keep updating the stored maximum to ensure future numbers can pair with the best possible partner
The beauty of this approach is its efficiency - we only need O(n)
time and minimal space (at most 81 different digit sums for numbers up to 10^9
).
Learn more about Sorting and Heap (Priority Queue) patterns.
Solution Approach
We implement the solution using a hash table to track the maximum value for each digit sum:
-
Initialize data structures:
- Create a hash table
d
(usingdefaultdict(int)
) to store the maximum number for each digit sum - Set
ans = -1
to track the maximum pair sum (returns-1
if no valid pair exists)
- Create a hash table
-
Process each number in the array: For each number
v
innums
:a. Calculate the digit sum:
x, y = 0, v while y: x += y % 10 y //= 10
x
accumulates the digit sumy % 10
extracts the last digity //= 10
removes the last digit- Continue until all digits are processed
b. Check for a valid pair:
- If digit sum
x
already exists in hash tabled
, we found a pair! - Calculate the pair sum:
d[x] + v
- Update the answer:
ans = max(ans, d[x] + v)
c. Update the hash table:
- Store or update the maximum value for this digit sum:
d[x] = max(d[x], v)
- This ensures future numbers with the same digit sum can pair with the best possible partner
-
Return the result:
- Return
ans
, which contains the maximum pair sum or-1
if no valid pair was found
- Return
Time Complexity: O(n × log M)
where n
is the array length and M
is the maximum value in the array (for digit sum calculation)
Space Complexity: O(k)
where k
is the number of unique digit sums (at most 81 for numbers up to 10^9
)
Optimization Note: Since the maximum possible digit sum is 81 (nine 9's), we could replace the hash table with a fixed-size array of length 100 for slightly better performance.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's trace through the solution with nums = [18, 43, 36, 13, 7]
:
Initial state:
- Hash table
d = {}
(empty) - Answer
ans = -1
Step 1: Process 18
- Calculate digit sum:
1 + 8 = 9
- Check if digit sum 9 exists in
d
: No - Update
d[9] = 18
- Current state:
d = {9: 18}
,ans = -1
Step 2: Process 43
- Calculate digit sum:
4 + 3 = 7
- Check if digit sum 7 exists in
d
: No - Update
d[7] = 43
- Current state:
d = {9: 18, 7: 43}
,ans = -1
Step 3: Process 36
- Calculate digit sum:
3 + 6 = 9
- Check if digit sum 9 exists in
d
: Yes!d[9] = 18
- Calculate pair sum:
18 + 36 = 54
- Update answer:
ans = max(-1, 54) = 54
- Update
d[9] = max(18, 36) = 36
- Current state:
d = {9: 36, 7: 43}
,ans = 54
Step 4: Process 13
- Calculate digit sum:
1 + 3 = 4
- Check if digit sum 4 exists in
d
: No - Update
d[4] = 13
- Current state:
d = {9: 36, 7: 43, 4: 13}
,ans = 54
Step 5: Process 7
- Calculate digit sum:
7
- Check if digit sum 7 exists in
d
: Yes!d[7] = 43
- Calculate pair sum:
43 + 7 = 50
- Update answer:
ans = max(54, 50) = 54
- Update
d[7] = max(43, 7) = 43
- Current state:
d = {9: 36, 7: 43, 4: 13}
,ans = 54
Final Result: 54
The algorithm found two valid pairs:
- Numbers with digit sum 9:
(18, 36)
with sum 54 - Numbers with digit sum 7:
(43, 7)
with sum 50
The maximum pair sum is 54, which comes from pairing 18 and 36.
Solution Implementation
1from collections import defaultdict
2from typing import List
3
4class Solution:
5 def maximumSum(self, nums: List[int]) -> int:
6 # Dictionary to store the maximum value for each digit sum
7 digit_sum_to_max_value = defaultdict(int)
8 # Initialize result to -1 (return -1 if no valid pair exists)
9 max_pair_sum = -1
10
11 # Iterate through each number in the array
12 for num in nums:
13 # Calculate the sum of digits for current number
14 digit_sum = 0
15 temp_num = num
16 while temp_num > 0:
17 digit_sum += temp_num % 10 # Add the last digit
18 temp_num //= 10 # Remove the last digit
19
20 # Check if we've seen this digit sum before
21 if digit_sum in digit_sum_to_max_value:
22 # Update max_pair_sum with the sum of current number
23 # and the largest number with same digit sum seen before
24 max_pair_sum = max(max_pair_sum, digit_sum_to_max_value[digit_sum] + num)
25
26 # Update the maximum value for this digit sum
27 digit_sum_to_max_value[digit_sum] = max(digit_sum_to_max_value[digit_sum], num)
28
29 return max_pair_sum
30
1class Solution {
2 public int maximumSum(int[] nums) {
3 // Array to store the maximum value for each possible digit sum (0-99)
4 // Index represents the digit sum, value represents the max number with that digit sum
5 int[] maxValueByDigitSum = new int[100];
6
7 // Initialize result as -1 (no valid pair found)
8 int maxPairSum = -1;
9
10 // Iterate through each number in the input array
11 for (int currentNum : nums) {
12 // Calculate the sum of digits for the current number
13 int digitSum = 0;
14 for (int temp = currentNum; temp > 0; temp /= 10) {
15 digitSum += temp % 10;
16 }
17
18 // Check if we've seen another number with the same digit sum
19 if (maxValueByDigitSum[digitSum] > 0) {
20 // Update the maximum pair sum if current pair is larger
21 maxPairSum = Math.max(maxPairSum, maxValueByDigitSum[digitSum] + currentNum);
22 }
23
24 // Update the maximum value for this digit sum
25 maxValueByDigitSum[digitSum] = Math.max(maxValueByDigitSum[digitSum], currentNum);
26 }
27
28 return maxPairSum;
29 }
30}
31
1class Solution {
2public:
3 int maximumSum(vector<int>& nums) {
4 // Array to store the maximum number for each digit sum (0-99)
5 // Since max number is 10^9, max digit sum is 9*9 = 81
6 int maxNumForDigitSum[100]{};
7
8 // Initialize result as -1 (no valid pair found)
9 int maxSum = -1;
10
11 // Process each number in the array
12 for (int currentNum : nums) {
13 // Calculate the sum of digits for current number
14 int digitSum = 0;
15 for (int temp = currentNum; temp > 0; temp /= 10) {
16 digitSum += temp % 10;
17 }
18
19 // If we've seen a number with the same digit sum before
20 if (maxNumForDigitSum[digitSum] > 0) {
21 // Update max sum with the pair sum (previous max + current)
22 maxSum = max(maxSum, maxNumForDigitSum[digitSum] + currentNum);
23 }
24
25 // Update the maximum number seen for this digit sum
26 maxNumForDigitSum[digitSum] = max(maxNumForDigitSum[digitSum], currentNum);
27 }
28
29 return maxSum;
30 }
31};
32
1/**
2 * Finds the maximum sum of two numbers from the array that have the same digit sum.
3 * @param nums - Array of positive integers
4 * @returns Maximum sum of two numbers with same digit sum, or -1 if no such pair exists
5 */
6function maximumSum(nums: number[]): number {
7 // Array to store the maximum value for each possible digit sum (0-99)
8 const maxValueByDigitSum: number[] = Array(100).fill(0);
9 let maxSum: number = -1;
10
11 for (const currentNum of nums) {
12 // Calculate the sum of digits for the current number
13 let digitSum: number = 0;
14 let tempNum: number = currentNum;
15
16 while (tempNum > 0) {
17 digitSum += tempNum % 10; // Add the last digit
18 tempNum = Math.floor(tempNum / 10); // Remove the last digit
19 }
20
21 // Check if we've seen another number with the same digit sum
22 if (maxValueByDigitSum[digitSum] > 0) {
23 // Update max sum if current pair has larger sum
24 maxSum = Math.max(maxSum, maxValueByDigitSum[digitSum] + currentNum);
25 }
26
27 // Update the maximum value seen for this digit sum
28 maxValueByDigitSum[digitSum] = Math.max(maxValueByDigitSum[digitSum], currentNum);
29 }
30
31 return maxSum;
32}
33
Time and Space Complexity
Time Complexity: O(n × log M)
The algorithm iterates through each element in the array once, which takes O(n)
time. For each element v
, it calculates the sum of digits by repeatedly dividing by 10 and extracting the remainder. The number of iterations in this digit extraction process is proportional to the number of digits in v
, which is O(log₁₀ v)
. Since the maximum value in the array is M
, the digit extraction takes at most O(log M)
time. Therefore, the overall time complexity is O(n × log M)
, where n
is the length of the array and M ≤ 10⁹
is the maximum value of elements in the array.
Space Complexity: O(D)
The algorithm uses a dictionary d
to store the maximum value for each digit sum. The number of unique digit sums is bounded by the maximum possible digit sum D
. For a number with maximum value M = 10⁹
, it has at most 9 digits, and each digit can be at most 9. Therefore, the maximum digit sum D = 9 × 9 = 81
. The dictionary can have at most D
entries, resulting in a space complexity of O(D)
, where D ≤ 81
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting to Update the Hash Table After Finding a Pair
A common mistake is to update the answer when finding a matching digit sum but forgetting to update the hash table with the current number. This causes the algorithm to miss potentially better pairs.
Incorrect Implementation:
for num in nums:
digit_sum = calculate_digit_sum(num)
if digit_sum in digit_sum_to_max_value:
max_pair_sum = max(max_pair_sum, digit_sum_to_max_value[digit_sum] + num)
else:
digit_sum_to_max_value[digit_sum] = num
# Missing: Update even when digit_sum exists!
Why this fails: If we have nums = [18, 36, 54]
where all have digit sum 9:
- After processing 18 and 36, we get pair sum 54
- When we reach 54, we don't update the hash table
- We miss the optimal pair (36, 54) with sum 90
Correct Solution:
for num in nums:
digit_sum = calculate_digit_sum(num)
if digit_sum in digit_sum_to_max_value:
max_pair_sum = max(max_pair_sum, digit_sum_to_max_value[digit_sum] + num)
# Always update to keep the maximum value for each digit sum
digit_sum_to_max_value[digit_sum] = max(digit_sum_to_max_value[digit_sum], num)
2. Integer Overflow in Digit Sum Calculation
While less common in Python, using the wrong data type or calculation method can cause issues.
Problematic Approach:
# Converting to string might seem easier but can be inefficient
digit_sum = sum(int(digit) for digit in str(num))
Better Approach:
digit_sum = 0 while num > 0: digit_sum += num % 10 num //= 10
The mathematical approach is more efficient and avoids string conversion overhead.
3. Not Handling the Case of No Valid Pairs
Forgetting to initialize the result to -1 or not properly checking if any valid pair was found.
Incorrect:
max_pair_sum = 0 # Wrong! Should be -1
Correct:
max_pair_sum = -1 # Correctly indicates "no valid pair found"
4. Using the Same Element Twice
While the hash table approach naturally avoids this, some alternative implementations might accidentally pair an element with itself.
Example to verify: For nums = [9]
, the algorithm should return -1, not 18 (9+9), since we need two different indices.
What are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)
Recommended Readings
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
https assets algo monster cover_photos heap svg Priority Queue and Heap What is the relationship between priority queue and heap Priority Queue is an Abstract Data Type and Heap is the concrete data structure we use to implement a priority queue Priority Queue A priority queue is a data structure
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Want a Structured Path to Master System Design Too? Don’t Miss This!