Facebook Pixel

3153. Sum of Digit Differences of All Pairs

MediumArrayHash TableMathCounting
Leetcode Link

Problem Description

You have an array nums containing positive integers where every integer has the same number of digits.

The digit difference between two integers is calculated by comparing the digits at each position and counting how many positions have different digits.

For example, if we have two numbers 123 and 125:

  • Position 1 (hundreds): both have 1 → same
  • Position 2 (tens): both have 2 → same
  • Position 3 (ones): 3 vs 5 → different
  • The digit difference is 1

Your task is to find the sum of digit differences for all possible pairs of integers in the array.

For instance, with nums = [123, 125, 143]:

  • Pair (123, 125): digit difference = 1
  • Pair (123, 143): digit difference = 2
  • Pair (125, 143): digit difference = 2
  • Total sum = 1 + 2 + 2 = 5

The solution works by processing each digit position separately. For each position, it counts how many times each digit (0-9) appears at that position across all numbers. If a digit d appears v times at a position, then it differs from the other n - v numbers at that position. The formula v × (n - v) gives the total differences involving digit d. Summing this for all digits and dividing by 2 (since each pair is counted twice) gives the contribution of that position to the total answer.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Instead of comparing every pair of numbers digit by digit (which would be inefficient), we can think about the problem from a different angle: process each digit position independently.

Consider what happens at a single digit position across all numbers. If we look at the rightmost digit position and see that digit 3 appears 4 times and digit 7 appears 2 times out of 6 total numbers, then:

  • The 4 numbers with digit 3 will each differ from the 2 numbers with digit 7 at this position
  • This contributes 4 × 2 = 8 to our total count

The key insight is that for any digit d appearing v times at a position, it contributes to the difference count with all the other n - v numbers that have a different digit at that position. So the contribution is v × (n - v).

By counting the frequency of each digit (0-9) at each position and applying this formula, we avoid redundant pair-by-pair comparisons. We sum up contributions from all digits at each position, then move to the next position.

Why divide by 2? When we calculate v × (n - v) for each digit, we're counting each pair twice. For example, if digit 3 appears 4 times and digit 7 appears 2 times, the formula counts both "3 differs from 7" and "7 differs from 3". So we divide the final sum by 2 to get the actual number of differing pairs.

The approach elegantly transforms an O(n² × m) brute force solution into an O(n × m) solution by leveraging counting and the symmetry of pairwise comparisons.

Learn more about Math patterns.

Solution Approach

The implementation follows the counting strategy described in the reference approach. Here's how the solution works step by step:

  1. Initialize variables:

    • Get the length of the array n = len(nums)
    • Calculate the number of digits m = int(log10(nums[0])) + 1 (since all numbers have the same digit count)
    • Initialize the answer ans = 0
  2. Process each digit position from right to left:

    • For each of the m digit positions, create a Counter to track digit frequencies
    • For each number in the array:
      • Extract the rightmost digit using divmod(x, 10) which returns quotient and remainder
      • The remainder y is the current digit we're examining
      • Update the number by removing its rightmost digit (storing the quotient back)
      • Count the occurrence of digit y in our Counter
  3. Calculate contribution for current position:

    • For each unique digit value v in our counter with its frequency:
      • Apply the formula: v × (n - v)
      • This counts how many times this digit differs from all other digits at this position
    • Sum all these contributions and divide by 2 (since each pair is counted twice)
    • Add this to our running total ans
  4. Return the final answer after processing all digit positions

The key formula used is:

sum(v × (n - v) for v in cnt.values()) // 2

This efficiently counts all pairwise differences at each digit position. The division by 2 corrects for double-counting since the difference between digits a and b is counted both when processing a and when processing b.

The time complexity is O(n × m) where n is the array length and m is the number of digits, which is much more efficient than the brute force O(n² × m) approach.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [13, 23, 12].

Step 1: Initialize

  • n = 3 (array length)
  • m = 2 (each number has 2 digits)
  • ans = 0

Step 2: Process the ones place (rightmost digit)

Create a counter for digit frequencies at this position:

  • Number 13: Extract digit 3, update to 1
  • Number 23: Extract digit 3, update to 2
  • Number 12: Extract digit 2, update to 1

Counter at ones place: {3: 2, 2: 1}

Calculate contribution:

  • Digit 3 appears 2 times → contributes 2 × (3 - 2) = 2 × 1 = 2
  • Digit 2 appears 1 time → contributes 1 × (3 - 1) = 1 × 2 = 2
  • Total for this position: (2 + 2) / 2 = 2

ans = 0 + 2 = 2

Step 3: Process the tens place (leftmost digit)

Our numbers are now [1, 2, 1] after removing the ones digit.

Create a counter for digit frequencies:

  • Number 1: Extract digit 1
  • Number 2: Extract digit 2
  • Number 1: Extract digit 1

Counter at tens place: {1: 2, 2: 1}

Calculate contribution:

  • Digit 1 appears 2 times → contributes 2 × (3 - 2) = 2 × 1 = 2
  • Digit 2 appears 1 time → contributes 1 × (3 - 1) = 1 × 2 = 2
  • Total for this position: (2 + 2) / 2 = 2

ans = 2 + 2 = 4

Verification: Let's verify by checking all pairs:

  • (13, 23): digits differ at both positions → difference = 2
  • (13, 12): digits differ at ones position only → difference = 1
  • (23, 12): digits differ at ones position only → difference = 1
  • Total = 2 + 1 + 1 = 4 ✓

The solution correctly computes the sum by processing each digit position independently and using the counting formula.

Solution Implementation

1class Solution:
2    def sumDigitDifferences(self, nums: List[int]) -> int:
3        # Get the number of integers in the input list
4        num_count = len(nums)
5      
6        # Calculate the number of digits in each number (assuming all have same length)
7        # log10(x) + 1 gives the number of digits in x
8        digit_count = int(log10(nums[0])) + 1
9      
10        # Initialize the total sum of digit differences
11        total_differences = 0
12      
13        # Process each digit position from right to left
14        for _ in range(digit_count):
15            # Counter to track frequency of each digit (0-9) at current position
16            digit_frequency = Counter()
17          
18            # Extract the rightmost digit from each number
19            for index, number in enumerate(nums):
20                # divmod(x, 10) returns (quotient, remainder)
21                # quotient becomes the new number (removing rightmost digit)
22                # remainder is the extracted rightmost digit
23                nums[index], current_digit = divmod(number, 10)
24                digit_frequency[current_digit] += 1
25          
26            # Calculate pairs with different digits at this position
27            # For each digit value, count * (total - count) gives pairs where
28            # one number has this digit and the other doesn't
29            # Divide by 2 to avoid counting each pair twice
30            total_differences += sum(
31                freq * (num_count - freq) for freq in digit_frequency.values()
32            ) // 2
33      
34        return total_differences
35
1class Solution {
2    public long sumDigitDifferences(int[] nums) {
3        // Get the total number of integers in the array
4        int arraySize = nums.length;
5      
6        // Calculate the number of digits in each integer (assuming all have same length)
7        int digitCount = (int) Math.floor(Math.log10(nums[0])) + 1;
8      
9        // Array to count frequency of each digit (0-9) at current position
10        int[] digitFrequency = new int[10];
11      
12        // Variable to store the total sum of digit differences
13        long totalDifferences = 0;
14      
15        // Process each digit position from right to left
16        for (int digitPosition = 0; digitPosition < digitCount; digitPosition++) {
17            // Reset frequency count for current digit position
18            Arrays.fill(digitFrequency, 0);
19          
20            // Count frequency of each digit at current position
21            for (int i = 0; i < arraySize; i++) {
22                // Get the rightmost digit and increment its frequency
23                int currentDigit = nums[i] % 10;
24                digitFrequency[currentDigit]++;
25              
26                // Remove the rightmost digit for next iteration
27                nums[i] /= 10;
28            }
29          
30            // Calculate contribution of current position to total differences
31            // For each digit, count pairs where digits are different
32            for (int digit = 0; digit < 10; digit++) {
33                // Number of pairs where one has 'digit' and other doesn't
34                // digitFrequency[digit] * (arraySize - digitFrequency[digit])
35                totalDifferences += (long) digitFrequency[digit] * (arraySize - digitFrequency[digit]);
36            }
37        }
38      
39        // Divide by 2 because each pair is counted twice
40        return totalDifferences / 2;
41    }
42}
43
1class Solution {
2public:
3    long long sumDigitDifferences(vector<int>& nums) {
4        int arraySize = nums.size();
5        // Calculate the number of digits in the first number
6        int digitCount = floor(log10(nums[0])) + 1;
7      
8        // Array to count frequency of each digit (0-9) at current position
9        int digitFrequency[10];
10        long long totalDifferences = 0;
11      
12        // Process each digit position from right to left
13        for (int position = 0; position < digitCount; ++position) {
14            // Reset frequency array for current digit position
15            memset(digitFrequency, 0, sizeof(digitFrequency));
16          
17            // Count frequency of each digit at current position
18            for (int i = 0; i < arraySize; ++i) {
19                int currentDigit = nums[i] % 10;  // Extract rightmost digit
20                ++digitFrequency[currentDigit];
21                nums[i] /= 10;  // Remove the processed digit
22            }
23          
24            // Calculate contribution to total differences for this position
25            // For each digit value, count pairs with different digits
26            for (int digit = 0; digit < 10; ++digit) {
27                // digitFrequency[digit] numbers have this digit
28                // (arraySize - digitFrequency[digit]) numbers have different digits
29                // Each pair contributes 1 to the difference count
30                totalDifferences += 1LL * digitFrequency[digit] * (arraySize - digitFrequency[digit]);
31            }
32        }
33      
34        // Divide by 2 because each pair is counted twice
35        // (once for each number in the pair)
36        return totalDifferences / 2;
37    }
38};
39
1/**
2 * Calculates the sum of digit differences across all pairs of numbers in the array.
3 * For each pair of numbers, it computes the sum of absolute differences at each digit position.
4 * 
5 * @param nums - Array of positive integers with the same number of digits
6 * @returns The total sum of digit differences for all pairs
7 */
8function sumDigitDifferences(nums: number[]): number {
9    // Get the total count of numbers in the array
10    const arrayLength: number = nums.length;
11  
12    // Calculate the number of digits in each number (assuming all have same digit count)
13    const digitCount: number = Math.floor(Math.log10(nums[0])) + 1;
14  
15    // Use BigInt to handle potentially large sums
16    let totalSum: bigint = BigInt(0);
17  
18    // Process each digit position from right to left
19    for (let digitPosition = 0; digitPosition < digitCount; digitPosition++) {
20        // Count frequency of each digit (0-9) at current position
21        const digitFrequency: number[] = Array(10).fill(0);
22      
23        // Extract digit at current position for each number
24        for (let i = 0; i < arrayLength; i++) {
25            // Get the rightmost digit
26            const currentDigit: number = nums[i] % 10;
27            digitFrequency[currentDigit]++;
28          
29            // Remove the rightmost digit for next iteration
30            nums[i] = Math.floor(nums[i] / 10);
31        }
32      
33        // Calculate contribution of current digit position to total sum
34        // For each digit value, multiply its frequency by count of numbers with different digits
35        for (let digit = 0; digit < 10; digit++) {
36            totalSum += BigInt(digitFrequency[digit]) * BigInt(arrayLength - digitFrequency[digit]);
37        }
38    }
39  
40    // Divide by 2 since each pair is counted twice (once for each order)
41    totalSum /= BigInt(2);
42  
43    // Convert back to regular number for return
44    return Number(totalSum);
45}
46

Time and Space Complexity

Time Complexity: O(n × m)

The algorithm iterates through m digits (where m is the number of digits in each number, calculated as int(log10(nums[0])) + 1). For each digit position, it processes all n numbers in the array. Within each iteration:

  • The loop iterates through all n numbers to extract the last digit and update the counter: O(n)
  • Computing the sum sum(v * (n - v) for v in cnt.values()) iterates through at most 10 distinct digits: O(1)

Therefore, the total time complexity is O(m × n).

Space Complexity: O(C) where C = 10

The space usage comes from:

  • The Counter object cnt which stores at most 10 different digit values (0-9) at any given time: O(10) = O(1)
  • A few scalar variables (n, m, ans, loop variables): O(1)
  • The input array nums is modified in-place, so no additional space proportional to input size is used

Since the maximum number of distinct digits is 10 (a constant), the space complexity is O(10) = O(C) where C is a constant equal to 10.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Modifying the Original Array In-Place

The biggest pitfall in this solution is that it destructively modifies the input array nums. After the function executes, all elements in nums become 0 because we repeatedly divide each number by 10 to extract digits.

Why this is problematic:

  • The caller might need the original values after calling this function
  • It violates the principle of least surprise - most functions don't modify their inputs unless explicitly designed to do so
  • Makes the function harder to test and debug since you can't call it twice with the same array

Solution: Create a copy of the array before processing:

def sumDigitDifferences(self, nums: List[int]) -> int:
    # Create a working copy to avoid modifying the original
    nums_copy = nums.copy()
    num_count = len(nums)
    digit_count = int(log10(nums[0])) + 1
    total_differences = 0
  
    for _ in range(digit_count):
        digit_frequency = Counter()
        for index, number in enumerate(nums_copy):
            nums_copy[index], current_digit = divmod(number, 10)
            digit_frequency[current_digit] += 1
      
        total_differences += sum(
            freq * (num_count - freq) for freq in digit_frequency.values()
        ) // 2
  
    return total_differences

2. Incorrect Digit Count Calculation for Edge Cases

Using int(log10(nums[0])) + 1 can fail or give incorrect results when:

  • nums[0] is 0 (causes domain error in log10)
  • Numbers have leading zeros after extraction (though this is less likely with positive integers)

Solution: Use a more robust method to count digits:

digit_count = len(str(nums[0]))

Or handle the zero case explicitly:

digit_count = 1 if nums[0] == 0 else int(log10(nums[0])) + 1

3. Not Handling Empty Arrays

The code assumes nums[0] exists to calculate digit count, which crashes on empty arrays.

Solution: Add an early return for edge cases:

def sumDigitDifferences(self, nums: List[int]) -> int:
    if not nums or len(nums) < 2:
        return 0  # No pairs possible
  
    # Rest of the implementation...
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

What's the output of running the following function using the following tree as input?

1def serialize(root):
2    res = []
3    def dfs(root):
4        if not root:
5            res.append('x')
6            return
7        res.append(root.val)
8        dfs(root.left)
9        dfs(root.right)
10    dfs(root)
11    return ' '.join(res)
12
1import java.util.StringJoiner;
2
3public static String serialize(Node root) {
4    StringJoiner res = new StringJoiner(" ");
5    serializeDFS(root, res);
6    return res.toString();
7}
8
9private static void serializeDFS(Node root, StringJoiner result) {
10    if (root == null) {
11        result.add("x");
12        return;
13    }
14    result.add(Integer.toString(root.val));
15    serializeDFS(root.left, result);
16    serializeDFS(root.right, result);
17}
18
1function serialize(root) {
2    let res = [];
3    serialize_dfs(root, res);
4    return res.join(" ");
5}
6
7function serialize_dfs(root, res) {
8    if (!root) {
9        res.push("x");
10        return;
11    }
12    res.push(root.val);
13    serialize_dfs(root.left, res);
14    serialize_dfs(root.right, res);
15}
16

Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More