3

Given the following:

protected bool IsPalindrome(uint x) // Samples: 1221, 456653
{

}

What's the best approach to determine if the input is a palindrome? Initially, I was trying out arrays by putting the input number into an array, reversing it in a for loop and assigning it to a temp array for comparison. However the indexing syntax got messy real fast, so I decided to simply treat the uint as a string.

Would the following be a valid solution in an interview whiteboard situation, or am I still over-complicating it?

protected bool IsPalindrome(uint x) 
{
    string givenNum = Convert.ToString(x);
    char[] input = givenNum.ToCharArray();
    Array.Reverse(input);

    string testString = String.Empty;
    foreach (char a in input)
        testString += a;

    if (givenNum == testString)
        return true;
    else
        return false;
}
IrishChieftain
  • 15,108
  • 7
  • 50
  • 91
  • If you think about it, do you really need to iterate through the entire array? Let's say you had a counter at both ends and moved towards to center with each iteration, does that help? Using that approach, you wouldn't need to call `Array.Reverse()` or anything. – Rion Williams May 04 '17 at 16:49
  • Interesting approach Rion but would that be a less "costly" operation than calling Reverse on the array? – IrishChieftain May 04 '17 at 16:54
  • 2
    in an interview situation i'd ask if the desired answer shall be short, or performance efficient ... – DarkSquirrel42 May 04 '17 at 16:54
  • Feels completely opinion based... I'd not accept converting number to char array as an answer. Using `%` and basic loop is only couple lines longer - http://stackoverflow.com/questions/829174/is-there-an-easy-way-to-turn-an-int-into-an-array-of-ints-of-each-digit... but `ToString` + `ToCharArray` can be turned inot good discussion... Or I definitely would look for some usage of Aggregate or Zip if you so inclined to go LINQ route. – Alexei Levenkov May 04 '17 at 16:59
  • 2
    Since we are talking about interview and not a real problem - I think solution with running two counters from both ends is better. Even better that you can implement it without converting anything to string. – Evk May 04 '17 at 16:59
  • Alexei, why would you not accept the number conversion approach? – IrishChieftain May 04 '17 at 17:10
  • 1
    @IrishChieftain Sorry for the delayed response. It would indeed be less costly (as you aren't allocating an additional array to store the reversed string, saving memory/storage _and_ you aren't always iterating through the entire string, and at most half of it, so it'll be guaranteed to be faster that way). My answer details this a bit more. – Rion Williams May 04 '17 at 17:25
  • 2
    I wouldn't either!! The whole point would be to do it with numbers, not strings. Otherwise they wouldn't specify a `uint` type. I would strongly advise you to not go in with only the idea of converting it to a string. (there is a mathematic way to solve it) – Rufus L May 04 '17 at 17:25
  • 1
    @IrishChieftain exactly what Rufus L said. As alternative we can get into conversation about number formatting (like 12321 get formatted into `"12,321"` and why `ToString` is actually ok in this case). The only real chance for `ToString` solution (with == from Traveling Guy) is "this is how I'd do it if I need quick and dirty code right now" (which very well could be enough if this is just warm up). But even that reeks [stringly typed code](https://blog.codinghorror.com/new-programming-jargon/) and sends bad message. – Alexei Levenkov May 04 '17 at 18:49

3 Answers3

5

Turn the number into a string, and if that string is equal to its reverse, it's a palindrome:

protected bool IsPalindrome(uint x) { 
    string test = x.ToString();
    string tset = new string(test.ToCharArray().Reverse().ToArray());
    return test == tset;
}
Traveling Tech Guy
  • 27,194
  • 23
  • 111
  • 159
  • 1
    Well that's just cheating... :) Don't you think the interviewer had a reason for specifying a `uint` type instead of a `string`?? – Rufus L May 04 '17 at 17:23
  • I don't see it as cheating at all. The interviewer wants to see how you approach a problem, and then how you solve it. By reducing a `uint` to `string`, you show initiative and "outside the box" approach. I'll hire someone who approaches any problem with "wait! this is just lie that other problem that has already been solved - all we need is a sound reduction" – Traveling Tech Guy May 04 '17 at 19:36
4

For efficiency you can do the following to get the reverse numerically and compare

protected bool IsPalindrome(uint x)
{
    uint original = x;
    uint reverse = 0;
    while (x > 0) 
    {
        reverse *= 10;
        reverse += x % 10;
        x /= 10;
    }

    return original == reverse;
}
juharr
  • 31,741
  • 4
  • 58
  • 93
1

NOTE: Since the question explicitly asks for the uint type as input, you can likely expect that the interviewer doesn't really want to see any string conversion approaches, but rather mathematical ones. See juharr's implementation for an example, which works similar to my second example, but replaces the use of strings with a bit of modulo arithmetic to determine correctness.

Short Answer

If you are already using the Array.Reverse() method, then you could simply compare the string to its reverse:

protected bool IsPalindrome(uint x)
{
    // Get your string
    var s = x.ToString();

    // Reverse it
    var characters = s.ToCharArray();
    Array.Reverse(characters);

    // If the original string is equal to the reverse, it's a palindrome
    return s == new string(characters);
}

More Efficient (and Possibly Interviewey) Answer

Within an interview setting, the interviewer might be looking for something that doesn't necessarily leverage all of the existing built-in functions within the language and might want a more bare-bones performant / algorithmic approach (e.g. keeping track of indices, and comparing positional values that might not require you to iterate through every single element).

An implementation that still uses string conversion this might look something like this response:

protected bool IsPalindrome(uint x)
{ 
    // Build your string
    var chars = x.ToString();

    // Iterate through half of the elements
    for (var i = 0; i < chars.Length / 2; i++)
    {
         // If they are ever not equal, then it's not a palindrome
         if (chars[i] != chars[chars.Length - 1 - i])
         {
              return false;
         }
    }

    // If you've made it through, then you have a palindrome
    return true;
}

Performance Comparisons

You can use a Stopwatch() class to actually see which of these performs better on a given dataset. Using 50,000 random integer values and the methods detailed above, I received the following results locally:

ShortAnswerApproachDuration: 00:00:00.0890155
  EfficientApproachDuration: 00:00:00.0693814

A few observations from this:

  • Since the efficient approach doesn't iterate through all of the elements each time and exits as soon as it recognizes the element is not a palindrome, it's much (~22% faster).
  • The efficient approach is also more efficient with regards to storage/memory as it doesn't need to store a copy of the reversed array either.

You can play around with changing the algorithm and testing it online here.

Other Considerations

Depending on how specific your interviewer wants to get, they might throw things like handling actual strings and sentences, handling punctuation and capitalization between those, which are pretty trivial adjustments (e.g. use things like case-insensitivity comparisons, etc.).

Community
  • 1
  • 1
Rion Williams
  • 74,820
  • 37
  • 200
  • 327
  • I think interviewer will be happy if you used mod division instead of converting to string. – Evk May 04 '17 at 17:09
  • Agreed, as an interviewer my first requirement would be that they can't just convert it to a string. Otherwise why specify that it has to be a `uint` type? – Rufus L May 04 '17 at 17:20
  • Beautiful and informative answer Rion, thanks for putting in the effort. Reading the comments, I have to concede that the interviewer wanted me to work with numbers based on the specific uint parameter. – IrishChieftain May 04 '17 at 17:42
  • 1
    No problem! I was just demonstrating a common use case of how this might work for string parameters (as nearly anything could be converted to one), but that also affects allocation. [juharr's solution](http://stackoverflow.com/a/43789022/557445) is probably specifically what your interviewer was looking for and it essentially uses the same premise as the "efficient" string approach, except without the string storage. It's worth noting that this could be outperformed by the string-based approach, but it ultimately depends on what you are looking for. – Rion Williams May 04 '17 at 18:57