2535. Difference Between Element Sum and Digit Sum of an Array
Problem Description
You are given a positive integer array nums
.
The problem asks you to calculate two different sums:
-
Element sum: This is simply the sum of all elements in the array. For example, if
nums = [15, 23, 8]
, the element sum would be15 + 23 + 8 = 46
. -
Digit sum: This is the sum of all individual digits that appear in the numbers within the array. For the same example
nums = [15, 23, 8]
, we would extract all digits:- From 15: digits are 1 and 5
- From 23: digits are 2 and 3
- From 8: digit is 8
- The digit sum would be
1 + 5 + 2 + 3 + 8 = 19
Your task is to return the absolute difference between these two sums, which is |element_sum - digit_sum|
.
The solution iterates through each number in the array. For each number v
, it adds v
to the element sum x
, and then extracts each digit of v
using modulo and integer division operations (v % 10
gives the last digit, v //= 10
removes the last digit) to add them to the digit sum y
. Since the element sum is always greater than or equal to the digit sum (a number is always greater than or equal to the sum of its digits), the code directly returns x - y
without needing the absolute value operation.
Intuition
The key observation is that we need to compute two separate sums from the same array - one treating each element as a whole number, and another breaking down each element into its individual digits.
The straightforward approach is to traverse the array once and calculate both sums simultaneously. For each number, we can:
- Add it directly to the element sum
- Extract its digits and add them to the digit sum
To extract digits from a number, we can use the mathematical property that n % 10
gives us the last digit of n
, and n // 10
removes the last digit. By repeatedly applying these operations until the number becomes 0, we can extract all digits.
An important insight is that the element sum will always be greater than or equal to the digit sum. This is because any multi-digit number is always greater than the sum of its digits (for example, 23 > 2 + 3
). Only single-digit numbers have equality. Therefore, we know that element_sum - digit_sum >= 0
, which means we don't actually need to use the absolute value function - we can directly return x - y
.
This single-pass approach is optimal because we only need to visit each element once, and for each element, we perform a constant amount of work (proportional to the number of digits, which is at most log10(n)
for a number n
).
Learn more about Math patterns.
Solution Approach
The solution uses a simulation approach where we traverse the array once and calculate both required sums simultaneously.
We initialize two variables:
x
to store the element sumy
to store the digit sum
For each number v
in the array nums
:
-
Add to element sum: We directly add
v
tox
usingx += v
-
Extract and sum digits: We use a while loop to extract each digit from
v
:v % 10
gives us the rightmost (last) digit- We add this digit to our digit sum
y
v //= 10
removes the last digit by integer division- We repeat until
v
becomes 0
The digit extraction process works because:
- For a number like
234
:- First iteration:
234 % 10 = 4
, add to sum, then234 // 10 = 23
- Second iteration:
23 % 10 = 3
, add to sum, then23 // 10 = 2
- Third iteration:
2 % 10 = 2
, add to sum, then2 // 10 = 0
- Loop ends when
v
becomes 0
- First iteration:
After processing all numbers, we return x - y
. Since the element sum is always greater than or equal to the digit sum (a number is always >=
the sum of its digits), we can return x - y
directly without needing the absolute value operation.
Time complexity: O(n * d)
where n
is the length of the array and d
is the average number of digits in each element.
Space complexity: O(1)
as we only use two variables regardless of input size.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with nums = [15, 23, 8]
.
Initialization:
x = 0
(element sum)y = 0
(digit sum)
Processing first element (15):
- Add to element sum:
x = 0 + 15 = 15
- Extract digits from 15:
15 % 10 = 5
, add to digit sum:y = 0 + 5 = 5
- Update:
15 // 10 = 1
1 % 10 = 1
, add to digit sum:y = 5 + 1 = 6
- Update:
1 // 10 = 0
- Loop ends as number becomes 0
Processing second element (23):
- Add to element sum:
x = 15 + 23 = 38
- Extract digits from 23:
23 % 10 = 3
, add to digit sum:y = 6 + 3 = 9
- Update:
23 // 10 = 2
2 % 10 = 2
, add to digit sum:y = 9 + 2 = 11
- Update:
2 // 10 = 0
- Loop ends
Processing third element (8):
- Add to element sum:
x = 38 + 8 = 46
- Extract digits from 8:
8 % 10 = 8
, add to digit sum:y = 11 + 8 = 19
- Update:
8 // 10 = 0
- Loop ends
Final calculation:
- Element sum:
x = 46
- Digit sum:
y = 19
- Return:
x - y = 46 - 19 = 27
The absolute difference between the element sum and digit sum is 27.
Solution Implementation
1class Solution:
2 def differenceOfSum(self, nums: List[int]) -> int:
3 """
4 Calculate the difference between the sum of elements and the sum of all digits.
5
6 Args:
7 nums: List of positive integers
8
9 Returns:
10 The absolute difference between element sum and digit sum
11 """
12 # Initialize variables for element sum and digit sum
13 element_sum = 0
14 digit_sum = 0
15
16 # Iterate through each number in the list
17 for number in nums:
18 # Add the number to the element sum
19 element_sum += number
20
21 # Extract and sum all digits of the current number
22 while number > 0:
23 # Get the last digit and add it to digit sum
24 digit_sum += number % 10
25 # Remove the last digit from the number
26 number //= 10
27
28 # Return the difference between element sum and digit sum
29 return element_sum - digit_sum
30
1class Solution {
2 public int differenceOfSum(int[] nums) {
3 // Calculate the element sum (sum of all array elements)
4 int elementSum = 0;
5 // Calculate the digit sum (sum of all digits in all elements)
6 int digitSum = 0;
7
8 // Iterate through each number in the array
9 for (int number : nums) {
10 // Add the current number to element sum
11 elementSum += number;
12
13 // Extract and sum all digits of the current number
14 int temp = number;
15 while (temp > 0) {
16 // Extract the rightmost digit and add to digit sum
17 digitSum += temp % 10;
18 // Remove the rightmost digit
19 temp /= 10;
20 }
21 }
22
23 // Return the absolute difference between element sum and digit sum
24 return elementSum - digitSum;
25 }
26}
27
1class Solution {
2public:
3 int differenceOfSum(vector<int>& nums) {
4 int elementSum = 0; // Sum of all elements in the array
5 int digitSum = 0; // Sum of all digits of all elements
6
7 // Iterate through each number in the array
8 for (int num : nums) {
9 // Add the current number to element sum
10 elementSum += num;
11
12 // Extract and sum all digits of the current number
13 while (num > 0) {
14 digitSum += num % 10; // Add the last digit to digit sum
15 num /= 10; // Remove the last digit
16 }
17 }
18
19 // Return the absolute difference between element sum and digit sum
20 return elementSum - digitSum;
21 }
22};
23
1/**
2 * Calculates the absolute difference between the sum of elements and the sum of digits
3 * @param nums - Array of positive integers
4 * @returns The difference between element sum and digit sum
5 */
6function differenceOfSum(nums: number[]): number {
7 let elementSum: number = 0;
8 let digitSum: number = 0;
9
10 // Iterate through each number in the array
11 for (const num of nums) {
12 // Add the current number to element sum
13 elementSum += num;
14
15 // Extract and sum all digits of the current number
16 let currentNumber: number = num;
17 while (currentNumber > 0) {
18 // Add the last digit to digit sum
19 digitSum += currentNumber % 10;
20 // Remove the last digit by integer division
21 currentNumber = Math.floor(currentNumber / 10);
22 }
23 }
24
25 // Return the difference between element sum and digit sum
26 return elementSum - digitSum;
27}
28
Time and Space Complexity
The time complexity is O(n × log₁₀ M)
, where n
is the length of the array nums
and M
is the maximum value of the elements in the array. This is because:
- The outer loop iterates through all
n
elements in the array - For each element
v
, the inner while loop extracts digits by repeatedly dividing by 10 untilv
becomes 0 - The number of digits in a number
v
is⌊log₁₀ v⌋ + 1
, which isO(log₁₀ M)
in the worst case whenv = M
- Therefore, the total time complexity is
O(n) × O(log₁₀ M) = O(n × log₁₀ M)
The space complexity is O(1)
because the algorithm only uses a constant amount of extra space with variables x
, y
, and v
, regardless of the input size.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Modifying the Original Value During Digit Extraction
A common mistake is directly modifying the loop variable when extracting digits, which causes the element sum calculation to be incorrect.
Incorrect Implementation:
for num in nums: element_sum += num while num > 0: # This modifies num! digit_sum += num % 10 num //= 10 # num is being changed here
This seems correct at first glance, but if you need to use num
again after the digit extraction (for debugging, logging, or future modifications), the value is lost.
Correct Solution:
for num in nums: element_sum += num temp = num # Create a copy for digit extraction while temp > 0: digit_sum += temp % 10 temp //= 10
2. Incorrect Handling of Single-Digit Numbers
Some might think single-digit numbers need special handling and add unnecessary complexity:
Overcomplicated Implementation:
for num in nums: element_sum += num if num < 10: digit_sum += num else: while num > 0: digit_sum += num % 10 num //= 10
Why It's Unnecessary: The while loop naturally handles single-digit numbers correctly. For a single digit like 8:
- First iteration:
8 % 10 = 8
, add to sum, then8 // 10 = 0
- Loop ends, having correctly added the digit
3. Using String Conversion (Less Efficient)
While not incorrect, converting numbers to strings for digit extraction is less efficient:
Less Efficient Approach:
for num in nums:
element_sum += num
for digit_char in str(num):
digit_sum += int(digit_char)
Why Mathematical Approach is Better:
- String conversion has overhead for memory allocation and type conversion
- Mathematical operations (%, //) are more direct and faster
- The mathematical approach uses O(1) space vs O(d) space for string conversion where d is the number of digits
4. Forgetting the Absolute Value (Problem-Specific)
While the current implementation correctly assumes element_sum >= digit_sum, if the problem were modified or if you're not certain about this property:
Safer Implementation:
return abs(element_sum - digit_sum)
This ensures correctness even if the assumption doesn't hold in edge cases or problem variations.
What does the following code do?
1def f(arr1, arr2):
2 i, j = 0, 0
3 new_arr = []
4 while i < len(arr1) and j < len(arr2):
5 if arr1[i] < arr2[j]:
6 new_arr.append(arr1[i])
7 i += 1
8 else:
9 new_arr.append(arr2[j])
10 j += 1
11 new_arr.extend(arr1[i:])
12 new_arr.extend(arr2[j:])
13 return new_arr
14
1public static List<Integer> f(int[] arr1, int[] arr2) {
2 int i = 0, j = 0;
3 List<Integer> newArr = new ArrayList<>();
4
5 while (i < arr1.length && j < arr2.length) {
6 if (arr1[i] < arr2[j]) {
7 newArr.add(arr1[i]);
8 i++;
9 } else {
10 newArr.add(arr2[j]);
11 j++;
12 }
13 }
14
15 while (i < arr1.length) {
16 newArr.add(arr1[i]);
17 i++;
18 }
19
20 while (j < arr2.length) {
21 newArr.add(arr2[j]);
22 j++;
23 }
24
25 return newArr;
26}
27
1function f(arr1, arr2) {
2 let i = 0, j = 0;
3 let newArr = [];
4
5 while (i < arr1.length && j < arr2.length) {
6 if (arr1[i] < arr2[j]) {
7 newArr.push(arr1[i]);
8 i++;
9 } else {
10 newArr.push(arr2[j]);
11 j++;
12 }
13 }
14
15 while (i < arr1.length) {
16 newArr.push(arr1[i]);
17 i++;
18 }
19
20 while (j < arr2.length) {
21 newArr.push(arr2[j]);
22 j++;
23 }
24
25 return newArr;
26}
27
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
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
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!