2443. Sum of Number and Its Reverse
Problem Description
Given a non-negative integer num
, determine if it can be expressed as the sum of any non-negative integer and its reverse. Return true
if such a pair exists, otherwise return false
.
For example, if num = 443
, we need to check if there exists a non-negative integer k
such that k + reverse(k) = 443
. In this case, k = 221
works because 221 + 122 = 443
, where 122
is the reverse of 221
.
The solution uses brute force enumeration to check all possible values of k
from 0
to num
. For each value k
, it calculates the reverse of k
by converting it to a string, reversing the string using slicing [::-1]
, and converting back to an integer. If k + reverse(k)
equals num
for any value of k
, the function returns true
.
The key insight is that if such a pair exists, at least one number in the pair must be less than or equal to num
, so checking all values from 0
to num
is sufficient to find the answer.
Intuition
When we need to find if a number can be expressed as the sum of some integer and its reverse, we need to think about the search space. If num = k + reverse(k)
for some non-negative integer k
, then k
must be at most num
(since both k
and reverse(k)
are non-negative).
This immediately gives us a bounded search space: we only need to check values of k
from 0
to num
. We don't need to check beyond num
because if k > num
, then k + reverse(k)
would definitely be greater than num
.
The brute force approach becomes viable because:
- We have a finite, bounded search space
[0, num]
- For each candidate
k
, checking ifk + reverse(k) = num
is a simple O(log k) operation (to reverse the digits) - We can stop as soon as we find any valid
k
The elegance of this solution lies in recognizing that we don't need any complex mathematical properties or optimizations - a simple exhaustive search within the bounded range is sufficient and straightforward to implement. The any()
function in Python makes this even more concise, as it will return true
as soon as it finds the first valid k
, providing short-circuit evaluation.
Learn more about Math patterns.
Solution Approach
The solution implements a brute force enumeration strategy to check all possible values of k
in the range [0, num]
.
The implementation uses a generator expression with Python's any()
function:
any(k + int(str(k)[::-1]) == num for k in range(num + 1))
Let's break down the algorithm step by step:
-
Iterate through candidates: Use
range(num + 1)
to generate all integers from0
tonum
inclusive. -
Reverse each number: For each candidate
k
:- Convert
k
to a string:str(k)
- Reverse the string using slice notation:
str(k)[::-1]
- Convert the reversed string back to an integer:
int(str(k)[::-1])
- Convert
-
Check the condition: Calculate
k + reverse(k)
and compare it withnum
. -
Short-circuit evaluation: The
any()
function returnstrue
as soon as it finds the firstk
wherek + reverse(k) == num
. If no suchk
exists after checking all values, it returnsfalse
.
The time complexity is O(n × log n), where n is the input num
. We iterate through n+1 values, and for each value, reversing the digits takes O(log k) time (proportional to the number of digits).
The space complexity is O(log n) for storing the string representation of numbers during the reversal process.
This brute force approach is practical because the search space is naturally bounded by the input value, and the reversal operation is computationally inexpensive.
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 walk through the solution with num = 443
:
We need to find if there exists a non-negative integer k
such that k + reverse(k) = 443
.
The algorithm checks each value from 0
to 443
:
k = 0
: reverse(0) = 0, so 0 + 0 = 0 ≠ 443k = 1
: reverse(1) = 1, so 1 + 1 = 2 ≠ 443k = 2
: reverse(2) = 2, so 2 + 2 = 4 ≠ 443- ...
k = 220
: reverse(220) = 022 = 22, so 220 + 22 = 242 ≠ 443k = 221
: reverse(221) = 122, so 221 + 122 = 443 ✓
When we reach k = 221
, we find that 221 + 122 = 443, which equals our target. The any()
function immediately returns true
without checking the remaining values from 222 to 443.
Let's trace through the reversal process for k = 221
:
- Convert to string: "221"
- Reverse using [::-1]: "122"
- Convert back to integer: 122
- Check: 221 + 122 = 443 = num ✓
For a number where no such pair exists, like num = 11
, the algorithm would check:
k = 0
: 0 + 0 = 0 ≠ 11k = 1
: 1 + 1 = 2 ≠ 11k = 2
: 2 + 2 = 4 ≠ 11- ...
k = 10
: 10 + 01 = 10 + 1 = 11 ✓
So num = 11
would return true
because k = 10
works.
Solution Implementation
1class Solution:
2 def sumOfNumberAndReverse(self, num: int) -> bool:
3 """
4 Check if there exists a non-negative integer k such that
5 k + reverse(k) equals num.
6
7 Args:
8 num: The target sum to check
9
10 Returns:
11 True if such a k exists, False otherwise
12 """
13 # Iterate through all possible values of k from 0 to num
14 # For each k, check if k plus its reverse equals num
15 return any(
16 k + int(str(k)[::-1]) == num
17 for k in range(num + 1)
18 )
19
1class Solution {
2 /**
3 * Checks if a given number can be expressed as the sum of any non-negative integer
4 * and its reverse.
5 *
6 * @param num The target number to check
7 * @return true if num can be expressed as x + reverse(x) for some x >= 0, false otherwise
8 */
9 public boolean sumOfNumberAndReverse(int num) {
10 // Iterate through all possible values of x from 0 to num
11 for (int originalNumber = 0; originalNumber <= num; ++originalNumber) {
12 // Calculate the reverse of the current number
13 int tempNumber = originalNumber;
14 int reversedNumber = 0;
15
16 // Build the reversed number digit by digit
17 while (tempNumber > 0) {
18 // Extract the last digit and append it to the reversed number
19 reversedNumber = reversedNumber * 10 + tempNumber % 10;
20 // Remove the last digit from the temporary number
21 tempNumber /= 10;
22 }
23
24 // Check if the sum of the original number and its reverse equals the target
25 if (originalNumber + reversedNumber == num) {
26 return true;
27 }
28 }
29
30 // No valid pair found
31 return false;
32 }
33}
34
1class Solution {
2public:
3 /**
4 * Checks if a given number can be expressed as the sum of any non-negative integer
5 * and its reverse.
6 *
7 * @param num The target number to check
8 * @return true if num can be expressed as x + reverse(x) for some x >= 0, false otherwise
9 */
10 bool sumOfNumberAndReverse(int num) {
11 // Iterate through all possible values of x from 0 to num
12 for (int candidate = 0; candidate <= num; ++candidate) {
13 // Calculate the reverse of the current candidate number
14 int temp = candidate;
15 int reversed = 0;
16
17 // Build the reversed number digit by digit
18 while (temp > 0) {
19 reversed = reversed * 10 + temp % 10; // Append the last digit of temp to reversed
20 temp /= 10; // Remove the last digit from temp
21 }
22
23 // Check if candidate + its reverse equals the target number
24 if (candidate + reversed == num) {
25 return true;
26 }
27 }
28
29 // No valid pair found
30 return false;
31 }
32};
33
1/**
2 * Checks if a number can be expressed as the sum of any non-negative integer and its reverse
3 * @param num - The target number to check
4 * @returns true if num can be expressed as i + reverse(i) for some i, false otherwise
5 */
6function sumOfNumberAndReverse(num: number): boolean {
7 // Iterate through all possible values from 0 to num
8 for (let i = 0; i <= num; i++) {
9 // Convert number to string, split into array of characters
10 const digitString: string = i.toString();
11 const digitArray: string[] = [...digitString];
12
13 // Reverse the array of digits and join back into string
14 const reversedArray: string[] = digitArray.reverse();
15 const reversedString: string = reversedArray.join('');
16
17 // Convert reversed string back to number
18 const reversedNumber: number = Number(reversedString);
19
20 // Check if current number plus its reverse equals the target
21 if (i + reversedNumber === num) {
22 return true;
23 }
24 }
25
26 // No valid pair found
27 return false;
28}
29
Time and Space Complexity
Time Complexity: O(n × log n)
, where n
is the value of num
.
The algorithm iterates through all integers from 0
to num
(inclusive), which gives us O(n)
iterations. For each iteration value k
, we perform:
- Converting
k
to a string:O(log k)
time (number of digits ink
) - Reversing the string:
O(log k)
time - Converting the reversed string back to integer:
O(log k)
time - Addition and comparison:
O(1)
time
Since k
can be at most n
, the operations inside the loop take O(log n)
time in the worst case. Therefore, the overall time complexity is O(n × log n)
.
Space Complexity: O(log n)
The space is used for:
- The string representation of
k
:O(log k)
space, which is at mostO(log n)
- The reversed string:
O(log k)
space, which is at mostO(log n)
- The generator expression uses constant additional space due to the
any()
function evaluating lazily
The space complexity is dominated by the string operations, resulting in O(log n)
total space complexity.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Inefficient Range Bound
The current solution checks all values from 0
to num
, but this is unnecessarily large. Since we need k + reverse(k) = num
, and reverse(k)
has at most the same number of digits as k
, we can establish that k
cannot exceed num
. However, a tighter bound exists: k
must be at most slightly greater than num/2
in most cases.
Optimization:
def sumOfNumberAndReverse(self, num: int) -> bool:
# More efficient: check up to num/2 + a small buffer
# Since k + reverse(k) = num, k is roughly num/2
upper_bound = (num // 2) + (10 ** (len(str(num)) // 2))
return any(
k + int(str(k)[::-1]) == num
for k in range(min(upper_bound, num + 1))
)
2. Leading Zeros in Reverse
When reversing a number that ends with zeros (e.g., 120
), the reverse becomes 021
which is interpreted as 21
. This is actually correct behavior for the problem, but developers might mistakenly think they need special handling.
Clarification: No fix needed - Python's int()
automatically handles leading zeros correctly:
# This works correctly:
k = 120
reverse_k = int(str(k)[::-1]) # Results in 21, not 021
3. Edge Case: num = 0
The solution correctly handles num = 0
(returns True
since 0 + 0 = 0
), but some might overlook testing this edge case or try to add unnecessary special handling.
4. Memory vs Speed Trade-off
Converting to string for reversal is convenient but creates temporary string objects. For problems with strict memory constraints, a mathematical approach might be preferred:
Alternative approach without string conversion:
def sumOfNumberAndReverse(self, num: int) -> bool:
def reverse_number(n):
result = 0
while n > 0:
result = result * 10 + n % 10
n //= 10
return result
return any(
k + reverse_number(k) == num
for k in range(num + 1)
)
5. Early Termination Opportunity
The current solution doesn't exploit the fact that if k + reverse(k) > num
, then all larger values of k
will also exceed num
(in most cases). While any()
provides short-circuiting for success, we could potentially break early on failure conditions too.
What's the output of running the following function using input 56
?
1KEYBOARD = {
2 '2': 'abc',
3 '3': 'def',
4 '4': 'ghi',
5 '5': 'jkl',
6 '6': 'mno',
7 '7': 'pqrs',
8 '8': 'tuv',
9 '9': 'wxyz',
10}
11
12def letter_combinations_of_phone_number(digits):
13 def dfs(path, res):
14 if len(path) == len(digits):
15 res.append(''.join(path))
16 return
17
18 next_number = digits[len(path)]
19 for letter in KEYBOARD[next_number]:
20 path.append(letter)
21 dfs(path, res)
22 path.pop()
23
24 res = []
25 dfs([], res)
26 return res
27
1private static final Map<Character, char[]> KEYBOARD = Map.of(
2 '2', "abc".toCharArray(),
3 '3', "def".toCharArray(),
4 '4', "ghi".toCharArray(),
5 '5', "jkl".toCharArray(),
6 '6', "mno".toCharArray(),
7 '7', "pqrs".toCharArray(),
8 '8', "tuv".toCharArray(),
9 '9', "wxyz".toCharArray()
10);
11
12public static List<String> letterCombinationsOfPhoneNumber(String digits) {
13 List<String> res = new ArrayList<>();
14 dfs(new StringBuilder(), res, digits.toCharArray());
15 return res;
16}
17
18private static void dfs(StringBuilder path, List<String> res, char[] digits) {
19 if (path.length() == digits.length) {
20 res.add(path.toString());
21 return;
22 }
23 char next_digit = digits[path.length()];
24 for (char letter : KEYBOARD.get(next_digit)) {
25 path.append(letter);
26 dfs(path, res, digits);
27 path.deleteCharAt(path.length() - 1);
28 }
29}
30
1const KEYBOARD = {
2 '2': 'abc',
3 '3': 'def',
4 '4': 'ghi',
5 '5': 'jkl',
6 '6': 'mno',
7 '7': 'pqrs',
8 '8': 'tuv',
9 '9': 'wxyz',
10}
11
12function letter_combinations_of_phone_number(digits) {
13 let res = [];
14 dfs(digits, [], res);
15 return res;
16}
17
18function dfs(digits, path, res) {
19 if (path.length === digits.length) {
20 res.push(path.join(''));
21 return;
22 }
23 let next_number = digits.charAt(path.length);
24 for (let letter of KEYBOARD[next_number]) {
25 path.push(letter);
26 dfs(digits, path, res);
27 path.pop();
28 }
29}
30
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!