Problem overview
The method absDiff takes two numbers, a and b, and returns how far apart they are, as a number that is never negative. This is the absolute value of a - b. The built-in Math.abs is off limits, so the sign has to be handled by hand.
Take absDiff(10, -1). The plain difference 10 - (-1) is 11, and that is the answer. For absDiff(0, 3) the plain difference 0 - 3 is -3, which is negative, so the answer is flipped to 3. For absDiff(-5, -7) the answer is 2, and for absDiff(1.5, 1.5) it is 0.
Approach
You could compute a - b and negate it when it is below zero, which is the same idea as the previous abs lesson. A shorter way is to decide up front which number is larger and subtract the smaller from it. A larger number minus a smaller number can't be negative.
So there are two cases. If a is smaller than b, the answer is b - a. Otherwise a is greater than or equal to b, and the answer is a - b. When the numbers are equal, both formulas give 0, so it doesn't matter which side takes the tie.
Step by step
- Write the test. Add an
ifwith its closing brace whose condition isa < b. - Return
b - ainside it. Whenais the smaller number, this subtraction is not negative. - Return
a - bafter theif. Noelseis needed. Ifa < bwas true, the method has already returned from inside theif, so this line is reached only whenais greater than or equal tob. In that casea - bis not negative.
The solution in TypeScript
class Solution {
absDiff(a: number, b: number): number {
if (a < b) {
return b - a;
}
return a - b;
}
}
Some details of the code:
- An early return replaces
else. Areturnends the method immediately, so the code after theifacts as the "otherwise" branch. Many programmers prefer this shape because it keeps the code flat. Writing theelseexplicitly would behave identically. - The annotations are for the compiler.
a: number,b: numberand the return type: numbervanish when tsc writes JavaScript, so nothing checks the arguments at run time. - Decimals work like integers. A
numberis a double-precision floating-point value, so the same code handles1.5and-7.
Edge cases and common mistakes
- Equal numbers. With
aequal tob, the condition is false and the method returnsa - b, which is 0. That is correct. - Negative inputs. Both numbers can be negative, as in
absDiff(-5, -7). The code never assumes a sign: it compares the numbers and subtracts, and-5 - (-7)is2. - Mixed signs. With
absDiff(6, -6),ais not belowb, so the result is6 - (-6), which is12. Subtracting a negative number adds its size. - Subtracting in a fixed order. Always returning
a - bfails wheneverais smaller thanb, because the answer comes out negative. The comparison is what fixes that. - Decimal rounding. Floating-point numbers are binary, so some decimals aren't exact.
absDiff(0.3, 0.1)gives0.19999999999999998, not0.2. This is how all doubles behave and not a fault of the method. Avoid comparing such results with===against a decimal literal. - NaN. If either input is
NaN, the comparison is false and the result isNaN.
Testing
These inputs cover each branch. Try them in the editor above:
absDiff(3, 0)should give3, which takes the second return.absDiff(0, 3)should give3, which takes the first return.absDiff(10, -1)should give11.absDiff(-5, -7)should give2.absDiff(1.5, 1.5)should give0.
The method makes one comparison and one subtraction, so it runs in constant time and uses constant space.