Go to “Reverse Integer (#7)” on Leetcode ↗
Ruby’s integers aren’t limited to 32-bits, so we don’t have to worry about overflows. However, if the problem insists that
0 must be returned if the number would overflow, we can then check if the reversed number would be greater than the largest 32-bit integer value, and return
0 if that’s the case. Most interviewers would probably be ok if you didn’t bothered with this bit, since it’s not the interesting part of the problem.
Solution 1: Stringify and Reverse
Most people would consider this cheating, but you could just turn the integer into a string, reverse that string, and turn it back into an integer. The only tricky part is when given a negative — we want to stringify and reverse the absolute value of the number (the positive part of it), and tack on the negative sign if the original number is negative.
INT32_MAX = 2 ** 31 - 1 INT32_MIN = -1 * 2 ** 31 def reverse(x) reversed_integer = x.abs.to_s.reverse.to_i solution = x < 0 ? -1 * reversed_integer : reversed_integer solution > INT32_MAX || solution < INT32_MIN ? 0 : solution end
Solution 2: Reverse a Digit Array
The modulo operator (
%) returns the remainder that would result from a division. We can use a repeated combination of
/ to extract all the digits from a number, one-by-one. If we
10 each time, we extract digits from right-to-left. We can append these digits to an array, such that the resulting array is in the order we want our solution to be.
Once we have this array, we can use place-value math to recombine them into the final number. For example, if we have the digits
[1, 2, 3, 4] in an array, and want to combine them into the number
1234, we’d multiple the
1 by 103, the
2 by 102, the
3 by 101, and the
4 by 100, and add all that together. If
n is the number of digits, each digit at index
I gets multiplied by 10n - 1 - I.
INT32_MAX = 2 ** 31 - 1 INT32_MIN = -1 * 2 ** 31 def reverse(x) x_copy = x.abs digits =  loop do digits << x_copy % 10 x_copy /= 10 break if x_copy == 0 end solution = 0 digits.each_with_index do |digit, index| place_value = 10 ** (digits.length - 1 - index) solution += digit * place_value end solution = x < 0 ? -1 * solution : solution solution > INT32_MAX || solution < INT32_MIN ? 0 : solution end
Solution 3: Digit By Digit
If we can’t (or don’t want to) allocate an additional array, we can do something similar, but we need to first determine what
n would be by running through a
/ loop first. Then, rather than looping through an array of digits, we use
% to extract a digit, and place-value multiplication to put it into the right place in the solution, within each iteration of the main loop.
INT32_MAX = 2 ** 31 - 1 INT32_MIN = -1 * 2 ** 31 def reverse(x) x_copy = x.abs n = 1 loop do x_copy /= 10 break if x_copy == 0 n += 1 end solution = 0 x_copy = x.abs (1..n).each do |i| place_value = 10 ** (n - i) next_digit = x_copy % 10 solution += next_digit * place_value x_copy /= 10 end solution = x < 0 ? -1 * solution : solution solution > INT32_MAX || solution < INT32_MIN ? 0 : solution end
Runtime: This solution is
O(log(x)) because both loops run as many iterations as there are digits in
x, and the work within both loops runs in constant time.
Memory: This solution uses a constant amount of memory.