

Reverse integer - C# solution for LeetCode problem
source link: https://msiyer.com/reverse-integer-csharp-solution-for-leetcode-problem/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Data Structures And Algorithms
Reverse integer - C# solution for LeetCode problem
C# solution for the reverse integer LeetCode problem
msiyer
The problem is simple - given a 32-bit integer A, return a 32-bit integer B which is A with all digits reversed. The detailed problem statement can be found at the LeetCode website. The solution is also trivial if you know basic Arithmetic and can wield it creatively. An important constraint mentioned is
Assume the environment does not allow you to store 64-bit integers (signed or unsigned).
Solutions
Naive solution
The first goal is to arrive at a solution. I do not care about the aesthetics of it as long as it works for all inputs. I also do not care about the constraints.
The remainder operator of C# is a great way to extract the last digit of any given integer x
. The remainder is the last digit when x
is divided by 10
.
int remainder = x % 10;
The remainder thus obtained is to be stored in a List<int>
. Also, the following will give us the integer x
, with its last digit removed
x = (x - remainder)/10;
With these two simple concepts sorted out, the bulk of the conceptual work is done. The algorithm to be followed is:
- extract digits out of the input integer and store the digits in a List<int>
- once all digits have been extracted and stored, get the stored digits and create an integer
The step 1 of the algorithm can be coded as
while(true)
{
/* if during the process of truncating the input integer x,
* it becomes smaller that 10 or in other words only the last
* digit remains, add it to the list and break loop
*/
if(x < 10)
{
list.Add(x);
break;
}
int remainder = x % 10;
/* this will remove the last digit from the input integer x.
* the above step has already detected the last digit of x and
* stored it in the "remainder" variable.
*/
x = (x - remainder)/10;
list.Add(remainder);
}
The step 2 of the algorithm can be coded as
double returnNumber = 0;
for(int i = 0; i < list.Count; i++)
{
int item = list[i];
if(item == 0)
continue;
/* the digits stored in the list need to be multiplied by the appropriate
* power of 10 to generate the output integer.
* the first digit in the list is multiplied by
* 10 ^ (number of digits in x - 1), second digit is
* multiplied by 10 ^ (number of digits in x - 1) and so on...
*/
returnNumber += item * Math.Pow(10, list.Count - i - 1);
}
The complete implementation follows. The code has enough comments to explain what is going on:
public class Solution
{
public int Reverse(int x)
{
List<int> list = new List<int>();
/* we need to keep track of the negativity :)
* if we do not, we forget about it during the extraction of digits
* while loop and also while creating the result integer
* in the for loop. The negativity will come back to bite us
* when we return the result. */
bool isNegative = x < 0 ? true : false;
if(isNegative)
x = x * -1;
/* how does this loop work?
* Example input = 123.
* first iteration:
* - is 123 < 10? No.
* - remainder = 123 % 10 = 3
* - x = (123 - 3)/10 = 12
* - list.Add(3)
* second iteration:
* - is 12 < 10? No.
* - remainder = 12 % 10 = 2
* - x = (12 - 2)/10 = 1
* - list.Add(2)
* third iteration:
* - is 1 < 10? Yes.
* - list.Add(1) and break */
while(true)
{
/* x has had its negativity removed above. if we had not done
* that this check would have let all negative x just pass
* through and break the loop.
*
* why not Math.Abs(x)?
* because it does not work for the following boundary value:
* -2147483648 (Int32.MinValue)
/* It throws a Runtime Error Message for -2147483648:
Unhandled exception. System.OverflowException: Negating the
minimum value of a twos complement number is invalid. */
if(x < 10)
{
list.Add(x);
break;
}
int remainder = x % 10;
x = (x - remainder)/10;
list.Add(remainder);
}
/* how does this loop work?
* list = {3, 2, 1}
* first iteration:
* - returnNumber = 0 + 3 * Math.Pow(10, 3 - 0 - 1) = 300
* second iteration:
* - returnNumber = 300 + 2 * Math.Pow(10, 3 - 1 - 1) = 320
* third iteration:
* - returnNumber = 320 + 1 * Math.Pow(10, 3 - 2 - 1) = 321 */
double returnNumber = 0;
for(int i = 0; i < list.Count; i++)
{
int item = list[i];
if(item == 0)
continue;
/* there is no power operator in C#. there is only
* Math.Pow() and it only deals with doubles (not integers).
* this is a blatant disregard of the following constraint:
* Assume the environment does not allow you to store 64-bit
* integers (signed or unsigned)
returnNumber += item * Math.Pow(10, list.Count - i - 1);
}
/* Convert.ToInt32() throws an OverflowException when input larger
* than Int32.MaxValue or Int32.MinValue.
* the other option of casting does not alert in any way if the
* conversion from double to integer fails.
* in effect, OverflowException in Convert.ToInt32() is the only way
* to know if the integer we generated as output is a valid one. */
try
{
if(isNegative)
Convert.ToInt32(returnNumber * -1);
else
Convert.ToInt32(returnNumber);
}
catch(Exception)
{
returnNumber = 0;
}
if(isNegative)
return (int)returnNumber * -1;
else
return (int)returnNumber;
}
}
Optimized solution
Analyzing the naive solution thoroughly we can easily see that the individual digits obtained by the application of remainder operator of C# need not be stored in a List<int>
. Rather, an integer variable would suffice
/* replace */
int remainder = x % 10;
list.Add(remainder);
/* with */
returnNumber = returnNumber * 10 + x % 10;
/* to get rid of List<int> storage */
Also, the digit extraction can be trivially optimized. Maybe, the compiler does this. However, nothing wrong in being exact in the code itself rather than hoping the compiler will optimize away our sloppiness
/* replace */
x = (x - remainder)/10;
/* with */
x = x/10;
The first optimization has a great cascading effect:
- We can get rid of the
for loop
we had employed for constructing the return value - With the
for loop
goes theMath.Pow()
- With removal of
Math.Pow()
goes away the need toConvert.ToInt32()
and theOverflowException
handling abomination - With all of the above we also have now gotten rid of the constraint violation.
The final optimized code is
public class Solution
{
public int Reverse(int x)
{
int returnNumber = 0;
while(true)
{
returnNumber = returnNumber * 10 + x % 10;
x = x/10;
if(Math.Abs(x) < 1) break;
if(returnNumber > Int32.MaxValue/10) return 0;
else if(returnNumber < Int32.MinValue/10) return 0;
}
return returnNumber;
}
}
Recommend
-
18
题目¶ 原题地址:https://leetcode.com/problems/reverse-linked-list/
-
9
The knapsack problem: Binary integer programming in SAS/IML 1 ...
-
7
Posted 2 years agoUpdated 2 months agoLeetCode /
-
8
Posted 2 years agoUpdated 2 months agoLeetCode /
-
6
This site can’t be reached The connection was reset.
-
6
Today’s Advent of Code (day 21 2022) was probably my favorite of the lot. I guess it’s a combination of having managed to solve it without relying on Reddit, having managed to solv...
-
1
Reverse Engineering a Neural Network's Clever Solution to Binary AdditionThere's a ton of attention lately on massive neural networks with billions of parameters, and rightly so. By combining huge parameter counts with powerful architect...
-
11
PROBLEM OF THE DAY: 04/10/2023October 05, 2023 |1.9K ViewsPROBLEM OF THE DAY: 04/10/2023 | Roman Number to IntegerMaths, Problem of the Day, Data Structures and Algorithms Save Sha...
-
8
Reverse alternate nodes in Linked ListOctober 07, 2023 |1.1K ViewsPROBLEM OF THE DAY: 06/10/2023 | Reverse alternate nodes in Linked ListProblem of the Day, linked-list, Data Structure and Alg...
-
5
Leetcode 25 Reverse Nodes in k-Group 题解分析-再解分析上一次主要是给了一个解题方案,没有具体讲解,这次又做到了就来看下几种方案,链表转置一直是我比较疑惑的问题,特别是边界处理,而这个问题要把难度加大了我先讲一下我一...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK