3
\$\begingroup\$

Problem

  • Count the number of character replacements necessary to convert an input String to a palindrome.
  • Each character replacement must replace the given character with the character directly before it in the alphabet (sorted A-Z).
  • In other words, D can only be replaced with C.
  • For simplicity, only consider Strings that are comprised of alphabetic characters.

Inspired by this HackerRank problem.

Example

  • A => already palindromic, so 0 character replacements are necessary
  • ACBD => ABBD => ABBC => ABBB => ABBA, 4 character replacements

Implementation

  • The solution is pretty basic, so maybe getting feedback is unnecessary, but is there a better implementation?
public class PalindromeConversionCounter {
  public static int count(String s) {
    int count = 0;
    char[] chars = s.toCharArray();
    for (int i = 0; i < Math.ceil(chars.length / 2); i++) {
      char currentChar = Character.toLowerCase(chars[i]);
      char oppositeChar = Character.toLowerCase(chars[chars.length - 1 - i]);
      if (!Character.isAlphabetic(currentChar) || !Character.isAlphabetic(oppositeChar)) {
        throw new IllegalArgumentException("String should contain only alphabetic characters");
      }
      count += Math.abs(currentChar - oppositeChar);
    }
    return count;
  }
}
\$\endgroup\$
1
\$\begingroup\$
    for (int i = 0; i < Math.ceil(chars.length / 2); i++) {
      char currentChar = Character.toLowerCase(chars[i]);
      char oppositeChar = Character.toLowerCase(chars[chars.length - 1 - i]);

You'll get the identical answer from Math.floor

    for (int i = 0; i < Math.floor(chars.length / 2.0); i++) {
      char currentChar = Character.toLowerCase(chars[i]);
      char oppositeChar = Character.toLowerCase(chars[chars.length - 1 - i]);

For one thing, you would get the integer result from the original since you were dividing two integers. But even if you fix that, realize that both return the same answer. Because when i == chars.length - 1 - i, the absolute value of the difference will always be zero. And that case is the one that the second version does not do.

    for (int i = 0; i < chars.length / 2; i++) {
      char currentChar = Character.toLowerCase(chars[i]);
      char oppositeChar = Character.toLowerCase(chars[chars.length - 1 - i]);

This does the same thing through the magic of integer math which implicitly takes the floor for you.

You can save some math by using two variables.

    for (int i = 0, j = chars.length - 1; i < j; i++, j--) {
      char currentChar = Character.toLowerCase(chars[i]);
      char oppositeChar = Character.toLowerCase(chars[j]);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.