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 `%` and `/` to extract all the digits from a number, one-by-one. If we `%` and `/` by `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.