17

Firstly here is the problem:

A positive integer is called a palindrome if its representation in the decimal system is the same when read from left to right and from right to left. For a given positive integer K of not more than 1000000 digits, write the value of the smallest palindrome larger than K to output. Numbers are always displayed without leading zeros.

Input: The first line contains integer t, the number of test cases. Integers K are given in the next t lines.

Output: For each K, output the smallest palindrome larger than K. Example

Input:

2

808

2133

Output:

818

2222

Secondly here is my code:

// I know it is bad practice to not cater for erroneous input,
// however for the purpose of the execise it is omitted
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.lang.Exception;
import java.math.BigInteger;

public class Main
{    
    public static void main(String [] args){   
        try{
            Main instance = new Main(); // create an instance to access non-static
                                        // variables
        
            // Use java.util.Scanner to scan the get the input and initialise the
            // variable
            Scanner sc=null;

            BufferedReader r = new BufferedReader(new InputStreamReader(System.in));

            String input = "";

            int numberOfTests = 0;

            String k; // declare any other variables here
            
            if((input = r.readLine()) != null){
                sc = new Scanner(input);
                numberOfTests = sc.nextInt();
            }

            for (int i = 0; i < numberOfTests; i++){
                if((input = r.readLine()) != null){
                    sc = new Scanner(input);
                    k=sc.next(); // initialise the remainder of the variables sc.next()
                    instance.palindrome(k);
                } //if
            }// for
        }// try

        catch (Exception e)
        {
            e.printStackTrace();
        }
    }// main

    public void palindrome(String number){

        StringBuffer theNumber = new StringBuffer(number);
        int length = theNumber.length();
        int left, right, leftPos, rightPos;
        // if incresing a value to more than 9 the value to left (offset) need incrementing
        int offset, offsetPos;
        boolean offsetUpdated;
        // To update the string with new values
        String insert;
        boolean hasAltered = false;

        for(int i = 0; i < length/2; i++){
            leftPos = i; 
            rightPos = (length-1) - i;
            offsetPos = rightPos -1; offsetUpdated = false;
            
            // set values at opposite indices and offset
            left = Integer.parseInt(String.valueOf(theNumber.charAt(leftPos)));
            right = Integer.parseInt(String.valueOf(theNumber.charAt(rightPos)));
            offset = Integer.parseInt(String.valueOf(theNumber.charAt(offsetPos)));

            if(left != right){
                // if r > l then offest needs updating
                if(right > left){
                    // update and replace
                    right = left;
                    insert = Integer.toString(right);

                    theNumber.replace(rightPos, rightPos + 1, insert);
                
                    offset++; if (offset == 10) offset = 0;
                    insert = Integer.toString(offset);

                    theNumber.replace(offsetPos, offsetPos + 1, insert);
                    offsetUpdated = true;
               
                    // then we need to update the value to left again
                    while (offset == 0 && offsetUpdated){ 
                        offsetPos--;
                        offset =
                            Integer.parseInt(String.valueOf(theNumber.charAt(offsetPos)));
                        offset++; if (offset == 10) offset = 0;
                        // replace
                        insert = Integer.toString(offset);
                        theNumber.replace(offsetPos, offsetPos + 1, insert);
                    }
                    // finally incase right and offset are the two middle values
                    left = Integer.parseInt(String.valueOf(theNumber.charAt(leftPos)));
                    if (right != left){
                        right = left;
                        insert = Integer.toString(right);
                        theNumber.replace(rightPos, rightPos + 1, insert);
                    }
                }// if r > l
                else
                    // update and replace
                    right = left;
                    insert = Integer.toString(right);
                    theNumber.replace(rightPos, rightPos + 1, insert);           
            }// if l != r
        }// for i
        System.out.println(theNumber.toString());
    }// palindrome
}

Finally my explaination and question.

My code compares either end and then moves in
    if left and right are not equal
        if right is greater than left
            (increasing right past 9 should increase the digit
             to its left i.e 09 ---- > 10) and continue to do
             so if require as for 89999, increasing the right
             most 9 makes the value 90000
        
             before updating my string we check that the right
             and left are equal, because in the middle e.g 78849887
             we set the 9 --> 4 and increase 4 --> 5, so we must cater for this.

The problem is from spoj.pl an online judge system. My code works for all the test can provide but when I submit it, I get a time limit exceeded error and my answer is not accepted.

Does anyone have any suggestions as to how I can improve my algorithm. While writing this question i thought that instead of my while (offset == 0 && offsetUpdated) loop i could use a boolean to to make sure i increment the offset on my next [i] iteration. Confirmation of my chang or any suggestion would be appreciated, also let me know if i need to make my question clearer.

Arnab Nandy
  • 6,472
  • 5
  • 44
  • 50
Mead3000
  • 581
  • 2
  • 5
  • 18

10 Answers10

44

This seems like a lot of code. Have you tried a very naive approach yet? Checking whether something is a palindrome is actually very simple.

private boolean isPalindrome(int possiblePalindrome) {
    String stringRepresentation = String.valueOf(possiblePalindrome);
    if ( stringRepresentation.equals(stringRepresentation.reverse()) ) {
       return true;
    }
}

Now that might not be the most performant code, but it gives you a really simple starting point:

private int nextLargestPalindrome(int fromNumber) {
    for ( int i = fromNumber + 1; ; i++ ) {
        if ( isPalindrome( i ) ) {
            return i;
        }
    }
}

Now if that isn't fast enough you can use it as a reference implementation and work on decreasing the algorithmic complexity.

There should actually be a constant-time (well it is linear on the number of digits of the input) way to find the next largest palindrome. I will give an algorithm that assumes the number is an even number of digits long (but can be extended to an odd number of digits).

  1. Find the decimal representation of the input number ("2133").
  2. Split it into the left half and right half ("21", "33");
  3. Compare the last digit in the left half and the first digit in the right half.
    a. If the right is greater than the left, increment the left and stop. ("22")
    b. If the right is less than the left, stop.
    c. If the right is equal to the left, repeat step 3 with the second-last digit in the left and the second digit in the right (and so on).
  4. Take the left half and append the left half reversed. That's your next largest palindrome. ("2222")

Applied to a more complicated number:

1.    1234567887654322
2.    12345678   87654322
3.    12345678   87654322
             ^   ^         equal
3.    12345678   87654322
            ^     ^        equal
3.    12345678   87654322
           ^       ^       equal
3.    12345678   87654322
          ^         ^      equal
3.    12345678   87654322
         ^           ^     equal
3.    12345678   87654322
        ^             ^    equal
3.    12345678   87654322
       ^               ^   equal
3.    12345678   87654322
      ^                 ^  greater than, so increment the left

3.    12345679

4.    1234567997654321  answer

This seems a bit similar to the algorithm you described, but it starts at the inner digits and moves to the outer.

Mark Peters
  • 80,126
  • 17
  • 159
  • 190
  • 3
    The number can have up to 1000000 digits so an int is out of the question. With your algorithm I for the number like 8999 increasing calues in the second half should have an effect on the first half – Mead3000 Oct 28 '11 at 21:19
  • 1
    @Mead: That probably means you can rule the naive approach out. For the algorithm I posted, there is nothing that says you ever need to store these things as binary numbers. You can just deal with Strings the entire time. – Mark Peters Oct 28 '11 at 21:24
  • Also for the algorithm I posted I'm not sure what trouble it would have handling `8999`. You'd end up incrementing `89` to `90` (since `9>8`) and would construct `9009`. There will be corner cases around something like `9999` though, when the number of digits increases. But I'll leave the corner cases (and dealing with odd digit numbers) to you. – Mark Peters Oct 28 '11 at 21:27
  • @Mark: What about when the output has more digits than the input ? Like the smallest palindrome larger than 99 = 101. And separately, I think in your algorithm you take the assumption that there will be an even number of digits in the input; am I wrong ? – Costi Ciudatu Oct 28 '11 at 21:45
  • @CostiCiudatu: It's not checking if the input is palindrome or not. – Bhesh Gurung Oct 28 '11 at 21:48
  • @Mark: I didn't refresh in time, so I didn't see your corner cases homework above, so ignore the above, I'll remove it anyways. – Costi Ciudatu Oct 28 '11 at 21:49
  • @BheshGurung: No, it's not. But since you mentioned that, does my comment seem to involve anything about checking the input ? Maybe I phrased it wrong... :-/ – Costi Ciudatu Oct 28 '11 at 21:53
  • 3
    you can improve this if you split the whole string / char traits, reverse the rhs substring and compare them. if the rhs is larger, increment lhs by one. afterwards result is lhs^lhs_reversed. for odd #digits just figure out if the middle char has to be incremented or not and do the obvious things – b.buchhold Oct 28 '11 at 21:58
  • @Mark Peter Hpw would you apply it to the number I have put in your answer 7499996381 – Mead3000 Oct 28 '11 at 22:05
  • @b.buchhold: That doesn't work unfortunately. Consider `234325`. 523 is greater than 234 so by your algorithm the next largest palindrome should be 235532. That is incorrect, as 234432 comes sooner. – Mark Peters Oct 28 '11 at 23:25
  • @Mead: Did you give it a try yourself? Where did you run into trouble? My algorithm seems pretty straight forward for that one. Also, please leave answer edits for answer corrections/improvements, not for asking for further help. – Mark Peters Oct 28 '11 at 23:28
  • @MarkPeters ok sorry. How do you propose I increment the left hand side i.e `1. 7493996381 2. 74939 96381 3. 74939 96381 '9' and '9'equal 4. 74939 96481 '3' and '6' so increment the lhs ` heres is where I have trouble, I cant increment the lhs as a decimal number because it is potentially 5*10^5 digits long. My other option is to increment the the last digit '9' which then should affect '3' (somewhat like my offset usage) and then would have to start the proces again. Am I wrong? or by incrementing the lhs can I then just append the reverse to get my palindrome? – Mead3000 Oct 29 '11 at 11:20
  • @Mead3000: To increment, I would start by seeing if something like `new BigInteger("74939").add(BigInteger.ONE).toString()` is performant enough (since it's a one-off operation, I wouldn't think it's too bad). It can deal with pretty much unlimited data. If that's not good enough you'll have to write your own digit-by-digit addition. The one thing you need to be careful about is if you end up adding a digit as a result, make sure you don't add two digits by mirroring it, but just one. – Mark Peters Oct 29 '11 at 16:02
  • I don't see any `reverse()` method in String class. – Anirban Nag 'tintinmj' Oct 06 '13 at 18:24
  • @tintinmj: You're right, that part was incorrect; I was just trying to give an idea of the algorithm. You can use `StringBuilder.reverse()` to reverse a string. – Mark Peters Oct 06 '13 at 18:56
  • Do you have any plans of fixing your answer to work with numbers of more than 30 digits? – Roland Illig Apr 20 '20 at 15:19
  • @RolandIllig: Not sure what you mean, the algorithm I included will work with tens of thousands of digits. – Mark Peters Apr 20 '20 at 15:53
  • You're right, the algorithm works with large numbers. But the code snippets don't. I meant the code snippets, sorry for being imprecise. – Roland Illig Apr 20 '20 at 20:41
  • Could you please remove the inefficient code snippets from the top of your answer? They are inappropriate for an accepted answer with so many upvotes. – Roland Illig Jun 14 '20 at 10:18
  • Please comment on the below case: 122 output will be 222, expected output should be 131 – vCillusion Oct 17 '20 at 13:47
18

There is no reason to fiddle with individual digits when the only needed operation is one simple addition. The following code is based on Raks' answer.

The code stresses simplicity over execution speed, intentionally.

import static org.junit.Assert.assertEquals;

import java.math.BigInteger;
import org.junit.Test;

public class NextPalindromeTest {

    public static String nextPalindrome(String num) {
        int len = num.length();
        String left = num.substring(0, len / 2);
        String middle = num.substring(len / 2, len - len / 2);
        String right = num.substring(len - len / 2);

        if (right.compareTo(reverse(left)) < 0)
            return left + middle + reverse(left);

        String next = new BigInteger(left + middle).add(BigInteger.ONE).toString();
        return next.substring(0, left.length() + middle.length())
             + reverse(next).substring(middle.length());
    }

    private static String reverse(String s) {
        return new StringBuilder(s).reverse().toString();
    }

    @Test
    public void testNextPalindrome() {
        assertEquals("5", nextPalindrome("4"));
        assertEquals("11", nextPalindrome("9"));
        assertEquals("22", nextPalindrome("15"));
        assertEquals("101", nextPalindrome("99"));
        assertEquals("151", nextPalindrome("149"));
        assertEquals("123454321", nextPalindrome("123450000"));
        assertEquals("123464321", nextPalindrome("123454322"));
    }
}
Roland Illig
  • 40,703
  • 10
  • 88
  • 121
14

Well I have constant order solution(atleast of order k, where k is number of digits in the number)

Lets take some examples suppose n=17208

divide the number into two parts from middle and reversibly write the most significant part onto the less significant one. ie, 17271 if the so generated number is greater than your n it is your palindrome, if not just increase the center number(pivot) ie, you get 17371

other examples

n=17286 palidrome-attempt=17271(since it is less than n increment the pivot, 2 in this case) so palidrome=17371

n=5684 palidrome1=5665 palidrome=5775

n=458322 palindrome=458854

now suppose n = 1219901 palidrome1=1219121 incrementing the pivot makes my number smaller here so increment the number adjacent pivot too 1220221

and this logic could be extended

Raks
  • 870
  • 3
  • 11
  • 27
  • I have used this same logic. However, there are many special cases that need to handled. E.g. what if n=999 or n=22 or n =10920. – Ashish K Agarwal Mar 14 '18 at 17:48
  • @AshishKAgarwal If you look at [my code that implements this exact answer](https://stackoverflow.com/a/46213830), you will see that a single `if` statement is enough to cover all your "many special cases". – Roland Illig Nov 20 '18 at 17:13
1

Here is my code in java. Whole idea is from here.

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("Enter number of tests: ");
        int t = sc.nextInt();

        for (int i = 0; i < t; i++) {
            System.out.println("Enter number: ");
            String numberToProcess = sc.next(); // ne proveravam dal su brojevi
            nextSmallestPalindrom(numberToProcess);
        }
    }

    private static void nextSmallestPalindrom(String numberToProcess) {
        

        int i, j;

        int length = numberToProcess.length();
        int[] numberAsIntArray = new int[length];
        for (int k = 0; k < length; k++)
            numberAsIntArray[k] = Integer.parseInt(String
                    .valueOf(numberToProcess.charAt(k)));

        numberToProcess = null;

        boolean all9 = true;
        for (int k = 0; k < length; k++) {
            if (numberAsIntArray[k] != 9) {
                all9 = false;
                break;
            }
        }
        // case 1, sve 9ke
        if (all9) {
            whenAll9(length);
            return;
        }

        int mid = length / 2;
        if (length % 2 == 0) {
            i = mid - 1;
            j = mid;
        } else {
            i = mid - 1;
            j = mid + 1;
        }
        
        while (i >= 0 && numberAsIntArray[i] == numberAsIntArray[j]) {
            i--;
            j++;
        }
        // case 2 already polindrom
        if (i == -1) {
            if (length % 2 == 0) {
                i = mid - 1;
                j = mid;
            } else {
                i = mid;
                j = i;
            }
            addOneToMiddleWithCarry(numberAsIntArray, i, j, true);

        } else {
            // case 3 not polindrom
            if (numberAsIntArray[i] > numberAsIntArray[j]) { // 3.1)
                
                while (i >= 0) {
                    numberAsIntArray[j] = numberAsIntArray[i];
                    i--;
                    j++;
                }
                for (int k = 0; k < numberAsIntArray.length; k++)
                    System.out.print(numberAsIntArray[k]);
                System.out.println();
            } else { // 3.2 like case 2
                if (length % 2 == 0) {
                    i = mid - 1;
                    j = mid;
                } else {
                    i = mid;
                    j = i;
                }
                addOneToMiddleWithCarry(numberAsIntArray, i, j, false);
            }
        }
    }

    private static void whenAll9(int length) {
        
        for (int i = 0; i <= length; i++) {
            if (i == 0 || i == length)
                System.out.print('1');
            else
                System.out.print('0');
        }
    }

    private static void addOneToMiddleWithCarry(int[] numberAsIntArray, int i,
            int j, boolean palindrom) {
        numberAsIntArray[i]++;
        numberAsIntArray[j] = numberAsIntArray[i];
        while (numberAsIntArray[i] == 10) {
            numberAsIntArray[i] = 0;
            numberAsIntArray[j] = numberAsIntArray[i];
            i--;
            j++;
            numberAsIntArray[i]++;
            numberAsIntArray[j] = numberAsIntArray[i];
        }
        
        if (!palindrom)
            while (i >= 0) {
                numberAsIntArray[j] = numberAsIntArray[i];
                i--;
                j++;
            }
        
        for (int k = 0; k < numberAsIntArray.length; k++)
            System.out.print(numberAsIntArray[k]);
        System.out.println();
    }

}
Arnab Nandy
  • 6,472
  • 5
  • 44
  • 50
uberchilly
  • 159
  • 1
  • 7
1
public class NextPalindrome 
{   
    int rev, temp;
    int printNextPalindrome(int n) 
    {
        int num = n;
        for (int i = num+1; i >= num; i++) 
        {
            temp = i;
            rev = 0;
            while (temp != 0) 
            {
                int remainder = temp % 10;
                rev = rev * 10 + remainder;
                temp = temp / 10;
            }
            if (rev == i) 
            {
                break;
            }
        }
        return rev;
    }
    public static void main(String args[]) 
    {
        NextPalindrome np = new NextPalindrome();
        int nxtpalin = np.printNextPalindrome(11);
        System.out.println(nxtpalin);
    }



}
Arunkumar Papena
  • 239
  • 2
  • 13
  • 1
    this is a horrible ans. – Mox Jan 20 '17 at 09:10
  • 1
    @Mox you should at least say _why_ this answer is horrible. It is horrible because (1) it only works for numbers up to 11 digits (2) it uses fields where local variables are more appropriate (3) `temp` is never an appropriate name for a field; the largest acceptable scope for a variable of that name is a block of about 3 lines, when used in a `swap` operation (4) the algorithm takes very long time to compute the next 10-digit palindrome (5) the name `NextPalindrome` is not suited to a class, it is appropriate for a method, though (6) the method `printNextPalindrome` doesn't print anything – Roland Illig Dec 02 '18 at 13:50
  • @RolandIllig thank you for your feedback. that comment is almost 2 years old. – Mox Dec 02 '18 at 13:52
0

Try this

public static String genNextPalin(String base){
    //check if it is 1 digit
    if(base.length()==1){
        if(Integer.parseInt(base)==9)
            return "11";
        else
            return (Integer.parseInt(base)+1)+"";
    }
    boolean check = true;
    //check if it is all 9s
    for(char a: base.toCharArray()){
        if(a!='9')
            check = false;
    }
    if(check){
        String num = "1";
        for(int i=0; i<base.length()-1; i++)
            num+="0";
        num+="1";
        return num;
    }

    boolean isBasePalin = isPalindrome(base);
    int mid = base.length()/2;
    if(isBasePalin){
        //if base is palin and it is odd increase mid and return
        if(base.length()%2==1){
            BigInteger leftHalf = new BigInteger(base.substring(0,mid+1));
            String newLeftHalf = leftHalf.add(BigInteger.ONE).toString();
            String newPalin = genPalin2(newLeftHalf.substring(0,mid),newLeftHalf.charAt(mid));
            return newPalin;
        }
        else{
            BigInteger leftHalf = new BigInteger(base.substring(0,mid));
            String newLeftHalf = leftHalf.add(BigInteger.ONE).toString();
            String newPalin = genPalin(newLeftHalf.substring(0,mid));
            return newPalin;
        }
    }
    else{
        if(base.length()%2==1){
            BigInteger leftHalf = new BigInteger(base.substring(0,mid));
            BigInteger rightHalf = new BigInteger(reverse(base.substring(mid+1,base.length())));

            //check if leftHalf is greater than right half
            if(leftHalf.compareTo(rightHalf)==1){
                String newPalin = genPalin2(base.substring(0,mid),base.charAt(mid));
                return newPalin;
            }
            else{
                BigInteger leftHalfMid = new BigInteger(base.substring(0,mid+1));
                String newLeftHalfMid = leftHalfMid.add(BigInteger.ONE).toString();
                String newPalin = genPalin2(newLeftHalfMid.substring(0,mid),newLeftHalfMid.charAt(mid));
                return newPalin;
            }
        }
        else{
            BigInteger leftHalf = new BigInteger(base.substring(0,mid));
            BigInteger rightHalf = new BigInteger(reverse(base.substring(mid,base.length())));

            //check if leftHalf is greater than right half
            if(leftHalf.compareTo(rightHalf)==1){
                return genPalin(base.substring(0,mid));
            }
            else{
                BigInteger leftHalfMid = new BigInteger(base.substring(0,mid));
                String newLeftHalfMid = leftHalfMid.add(BigInteger.ONE).toString(); 
                return genPalin(newLeftHalfMid);
            }
        }
    }
}

public static String genPalin(String base){
    return base + new StringBuffer(base).reverse().toString();
}
public static String genPalin2(String base, char middle){
    return base + middle +new StringBuffer(base).reverse().toString();
}

public static String reverse(String in){
    return new StringBuffer(in).reverse().toString();
}

static boolean isPalindrome(String str) {    
    int n = str.length();
    for( int i = 0; i < n/2; i++ )
        if (str.charAt(i) != str.charAt(n-i-1)) 
            return false;
    return true;    
}
Eric Kim
  • 10,617
  • 4
  • 29
  • 31
-1

HI Here is another simple algorithm using python,

  def is_palindrome(n):
      if len(n) <= 1:
          return False
      else:
          m = len(n)/2
          for i in range(m):
              j = i + 1
              if n[i] != n[-j]:
                  return False
          return True

  def next_palindrome(n):
      if not n:
          return False
      else:
          if is_palindrome(n) is True:
              return n
          else:
             return next_palindrome(str(int(n)+1))

  print next_palindrome('1000010')
James Sapam
  • 16,036
  • 12
  • 50
  • 73
-1

I have written comments to clarify what each step is doing in this python code.

One thing that need to be taken into consideration is that input can be very large that we can not simply perform integer operations on it. So taking input as string and then manipulating it would be much easier.

tests = int(input())
results = []
for i in range(0, tests):
    pal = input().strip()
    palen = len(pal)
    mid = int(palen/2)
    if palen % 2 != 0:
        if mid == 0: # if the number is of single digit e.g. next palindrome for 5 is 6 
            ipal = int(pal)
            if ipal < 9:
                results.append(int(pal) + 1)
            else:
                results.append(11) # for 9 next palindrome will be 11
        else:
            pal = list(pal)
            pl = l = mid - 1
            pr = r = mid + 1
            flag = 'n' # represents left and right half of input string are same
            while pl >= 0:
                if pal[pl] > pal[pr]:
                    flag = 'r' # 123483489 in this case pal[pl] = 4 and pal[pr] = 3 so we just need to copy left half in right half
                    break      # 123484321 will be the answer
                elif pal[pl] < pal[pr]:
                    flag = 'm' # 123487489 in this case pal[pl] = 4 and pal[pr] = 9 so copying left half in right half will make number smaller
                    break # in this case we need to take left half increment by 1 and the copy in right half 123494321 will be the anwere
                else:
                    pl = pl -1
                    pr = pr + 1
            if flag == 'm' or flag == 'n': # increment left half by one and copy in right half
                if pal[mid] != '9': # if mid element is < 9 the we can simply increment the mid number only and copy left in right half
                        pal[mid] = str(int(pal[mid]) + 1)
                        while r < palen:
                            pal[r] = pal[l]
                            r = r + 1
                            l = l - 1
                        results.append(''.join(pal))
                else: # if mid element is 9 this will effect entire left half because of carry
                    pal[mid] = '0' # we need to take care of large inputs so we can not just directly add 1 in left half
                    pl = l
                    while pal[l] == '9':
                        pal[l] = '0'
                        l = l - 1
                    if l >= 0:
                        pal[l] = str(int(pal[l]) + 1)
                    while r < palen:
                        pal[r] = pal[pl]
                        r = r + 1
                        pl = pl - 1
                    if l < 0:
                        pal[0] = '1'
                        pal[palen - 1] = '01'
                    results.append(''.join(pal))
            else:
                while r < palen: # when flag is 'r'
                    pal[r] = pal[l]
                    r = r + 1
                    l = l - 1
                results.append(''.join(pal))
    else: # even length almost similar concept here with flags having similar significance as in case of odd length input
        pal = list(pal)
        pr = r = mid
        pl = l = mid - 1
        flag = 'n'
        while pl >= 0:
            if pal[pl] > pal[pr]:
                flag = 'r'
                break
            elif pal[pl] < pal[pr]:
                flag = 'm'
                break
            else:
                pl = pl -1
                pr = pr + 1
        if flag == 'r':
            while r < palen:
                    pal[r] = pal[l]
                    r = r + 1
                    l = l - 1
            results.append(''.join(pal))
        else:
            if pal[l] != '9':
                pal[l] = str(int(pal[l]) + 1)
                while r < palen:
                    pal[r] = pal[l]
                    r = r + 1
                    l = l - 1
                results.append(''.join(pal))
            else:
                pal[mid] = '0'
                pl = l
                while pal[l] == '9':
                    pal[l] = '0'
                    l = l - 1
                if l >= 0:
                    pal[l] = str(int(pal[l]) + 1)
                while r < palen:
                    pal[r] = pal[pl]
                    r = r + 1
                    pl = pl - 1
                if l < 0:
                    pal[0] = '1'
                    pal[palen - 1] = '01'
                results.append(''.join(pal))

for xx in results:
    print(xx) 
quintin
  • 812
  • 1
  • 10
  • 35
  • I have provided comments in code to make things clear. If there is any specific reason for vote down or If it is failing for any test case please comment. – quintin Sep 20 '17 at 07:18
  • 1
    (1) your code is much longer than necessary (2) it doesn't define a properly named function to express an abstraction (3) `xx` is a bad variable name since it doesn't carry any information to the human reader (4) there are no paragraphs in the code to give the reader a chance to stop reading and take a breath (5) it uses magic values n, r, m for a flag; a flag usually has boolean type (6) it's not clear at all what `results` contains since it is printed in a loop, whereas `nextPalindrome` should clearly return a single string or number. – Roland Illig Dec 02 '18 at 13:56
-1

We can find next palindrome easily like below.

private void findNextPalindrom(int i) {
    i++;
    while (!checkPalindrom(i)) {
        i++;
    }
    Log.e(TAG, "findNextPalindrom:next palindrom is===" + i);
}


private boolean checkPalindrom(int num) {
    int temp = num;
    int rev = 0;
    while (num > 0) {
        int rem = num % 10;
        rev = rev * 10 + rem;
        num = num / 10;
    }
    return temp == rev;
}
Tarun Anchala
  • 2,232
  • 16
  • 15
  • This approach works only for very small numbers. The OP was asking for a solution that works for numbers with 1000 digits as well. – Roland Illig Jan 24 '22 at 21:33
-2

Simple codes and test output:

class NextPalin
{
public static void main( String[] args )
{
    try {
        int[] a = {2, 23, 88, 234, 432, 464, 7887, 7657, 34567, 99874, 7779222, 2569981, 3346990, 229999, 2299999 };
        for( int i=0; i<a.length; i++)
        {
            int add = findNextPalin(a[i]);
            System.out.println( a[i] + "  +  "  + add +  "  = "  + (a[i]+add)  );
        }
    }
    catch( Exception e ){}
}

static int findNextPalin( int a ) throws Exception
{
    if( a < 0 ) throw new Exception();
    if( a < 10 ) return a;

    int count = 0, reverse = 0, temp = a;
    while( temp > 0 ){
        reverse = reverse*10 + temp%10;
        count++;
        temp /= 10;
    }

    //compare 'half' value
    int halfcount = count/2;
    int base = (int)Math.pow(10, halfcount );
    int reverseHalfValue = reverse % base;
    int currentHalfValue = a % base;

    if( reverseHalfValue == currentHalfValue ) return 0;
    if( reverseHalfValue > currentHalfValue )  return  (reverseHalfValue - currentHalfValue);

    if(  (((a-currentHalfValue)/base)%10) == 9 ){
        //cases like 12945 or 1995
        int newValue = a-currentHalfValue + base*10;
        int diff = findNextPalin(newValue);
        return base*10 - currentHalfValue + diff;
    }
    else{
        return (base - currentHalfValue + reverseHalfValue );
    }
}
}

$ java NextPalin
2  +  2  = 4
23  +  9  = 32
88  +  0  = 88
234  +  8  = 242
432  +  2  = 434
464  +  0  = 464
7887  +  0  = 7887
7657  +  10  = 7667
34567  +  76  = 34643
99874  +  25  = 99899
7779222  +  555  = 7779777
2569981  +  9771  = 2579752
3346990  +  443  = 3347433
229999  +  9933  = 239932
2299999  +  9033  = 2309032
  • 3
    (1) A code dump is not an answer. Perhaps explain what you did, how it works, etc. (2) You did see that part about the number having up to a million digits, right? Ints aren't gonna work...not by a longshot. – cHao Jun 18 '13 at 04:28