Problem overview
The method biggestDigitSum gets an array of whole numbers nums and returns the number whose digits add up to the most. The digit sum of 472 is 4 + 7 + 2 = 13. If two numbers have the same digit sum, the one that comes first wins. The method returns the number itself, not its digit sum.
For [472, 95, 1000] the digit sums are 13, 14 and 1, so the answer is 95. For [19, 55, 28] all three sums are 10, so the first, 19, wins the tie. For [0, 7] the sums are 0 and 7, so the answer is 7. The numbers are between 0 and 1,000,000,000, and none is negative.
Approach: a helper for the digit sum
The work is split in two methods. The helper digitSum turns one number into the sum of its digits. biggestDigitSum then walks through the array, keeping the best number so far and replacing it only when a number has a strictly bigger digit sum.
To get the digits of a number, take the last one with n % 10 (the remainder after dividing by 10), add it to a total, and then drop it by dividing n by 10 and rounding down. Repeat until n is 0.
Step by step
- In
digitSum, starttotalat 0. Ifnis 0 the loop never runs, and 0 is the right answer. - Loop while
n > 0. Each turn removes one digit, sonreaches 0 once every digit is gone. - Add the last digit:
total += n % 10. For 472,472 % 10is 2. - Drop the last digit:
n = Math.floor(n / 10). In JavaScript,/keeps the fraction:472 / 10is 47.2.Math.floorrounds it down to 47. - Return
totalafter the loop. - In
biggestDigitSum, startbestatnums[0]. Before any comparison, the first number is the best one seen. - Loop over the numbers with
for (let num of nums). The first pass compares the first number with itself, which changes nothing. - Compare digit sums: if
this.digitSum(num)is greater thanthis.digitSum(best), setbesttonum. Use>, not>=, so a tie keeps the earlier number. - Return
best, the number itself.
The solution in JavaScript
class Solution {
digitSum(n) {
let total = 0;
while (n > 0) {
total += n % 10;
n = Math.floor(n / 10);
}
return total;
}
biggestDigitSum(nums) {
let best = nums[0];
for (let num of nums) {
if (this.digitSum(num) > this.digitSum(best)) {
best = num;
}
}
return best;
}
}
Some details:
- Division does not truncate. JavaScript has one number type, and
/always divides exactly. WithoutMath.floor,nwould go 472, 47.2, 4.72, 0.472 and keep shrinking through hundreds of turns, and each turn adds a fractional remainder:47.2 % 10is about 7.2. For 472 the "sum" ends up near 14.44 instead of 13. - Parameters can be changed. The helper assigns to
n. That only changes its own copy of the number; the caller's array is untouched. - The helper is called twice per comparison. That is simple and fast enough for this lesson.
Following 472
With n = 472 and total = 0, the first turn adds 472 % 10, which is 2, so total becomes 2, and n becomes Math.floor(47.2), which is 47. The second turn adds 7, so total is 9, and n becomes 4. The third turn adds 4, so total is 13, and n becomes 0. The condition n > 0 is now false, and the helper returns 13. A number such as 1000 passes through the zeros: three turns add 0 each, and the last adds 1.
In biggestDigitSum, the first example starts with best = 472 (sum 13). The number 472 is compared with itself and loses, 95 has sum 14 so it replaces best, and 1000 has sum 1 so it does not. The method returns 95.
In the tie example [19, 55, 28], every digit sum is 10. Because the comparison is strict, 55 does not replace 19 (10 is not greater than 10), and neither does 28. The method returns 19, the first of the three. In [0, 7], the helper returns 0 for the number 0 without entering the loop, and 7 has the bigger sum, so 7 wins.
Testing
The helper on single numbers: digitSum(472) is 13, digitSum(95) is 14, digitSum(1000) is 1 and digitSum(0) is 0. On the statement's examples, the solution prints:
95
19
7
Common mistakes
- Using
>=in the comparison. On a tie the later number would replace the earlier one. For[19, 55, 28]that version returns 28, not 19. - Leaving out
Math.floor. The number stays a fraction, and the digit sum is no longer a sum of whole digits. - Returning the digit sum. The method returns the number whose digits add up the most: 95, not 14.
- Calling the helper without
this.inside the class, which throws "digitSum is not defined".
