简体   繁体   中英

Algorithm to find number of palindromes in interval

I'm currently tasked with writing a program that calculates amount of palindromes in any base from interval of <2;36> . The problem is that my solution has time complexity of O(n^2) at best and that is, if I was frank, really slow.

So far I've tried naive solutions such as converting all numbers from the interval to the base that is required, saving the conversion of the number to array and then checking each of the elements one by one.

This is what I've got so far:

int isTrue = 1;
int arr[64];

while(n > 0)
{
   arr[counter] = n % base;
   n = n / base;
   counter++;
}

for(int i = 0; i < counter; i ++)
{
   if(arr[i] != arr[counter - i - 1])
   {
      isTrue = 0;
      break;
   }
}

It is not good by any stretch, but it does work for the basic test. The problem is that I'm currently trying to solve bonus one which works with much bigger numbers.

By much bigger numbers I mean intervals that span billions of numbers, one of the inputs is for example this:

c 15 62103360044 155888062462
Result : 123502

Where c is task that the program is supposed to do (there was option of l which listed all palindromes which doesn't occur in the bonus tests), 15 is base and the two other numbers are the limits of the interval.

I'm supposed to count palindromes of five such intervals under one second and honestly, I'm pretty stuck.

I would appreciate any help, I'm sorry if I formatted my question wrongly or if it was too drawn out - This is the first time I've asked a question here.

  • Doing a palindrome check faster is a minor optimisation. Initially I would even use java's number to String conversion.

  • What you want is to step through the interval in larger leaps.

  • You can use recursion for simplification in the initial version of your algorithm.

Let's look for base 10:

 62_103_360_044
155_888_062_462

 6 ...        6 (recursion on the middle part)
 7 ...        7
 8 ...        8
 9 ...        9
1 ...         1

You need:

  • Number of digits (your counter )
  • First most significant digit
  • Parameters start and end

For this step you only need to increment one digit, which even may be done as char.

Notice also that the recursive call on... gives the same result for 7, 8 and 9 with start 000..000 and end 999..999.

This will be tremendously faster. Happy coding.


Usage of recursion: I am not giving a clean answer, as that would defeat the task's challenge.

public BigInteger palindromesInInterval(int base, BigInteger from, BigInteger to) {
    return palindromesRec(base, from.toString(base), to.toString(base));
}

private BigInteger palindromesRec(int base, String from, String to) {
    // Do the simple work:
    if (from.length() > to.length()) {
        return BigInteger.ZERO;
    }
    if (from.length() == to.length() && from.compareTo(to) > 0) {
        return BigInteger.ZERO;
    }
    if (from.length() == 1) {
        ...
    }
    // Do a step:
    int highDigit = Integer.parseInt(from.substring(0, 1), base);
    int lowDigit = Integer.parseInt(from.substring(from.length() - 1), base);

    BigInteger sum = BigInteger.ZERO;
    int digit = Math.max(highDigit, lowDigit);
    String from2 = from.substring(1, from.length() - 2); // Can start with 0
    String to2 = "1000...000" -1; // Niners so to say.
    while (digit < base) {
         ...
         sum = sum.add(palidromesRec(base, from2, to2)); // RECURSION
         from2 = "000...000";
    }
    ...
    return sum;
}

Recursion calling oneself, here only once, without extra parameters, which often are used. For instance it is much easier to split the work in:

from  6 2_103_360_04 4
  to  9 9 ..       9 9

from 1 00 ..       0 1
  to 1 55_888_062_46 2

And calculate for every X

from X 000 X   (n zeroes)
  to X 999 X   (n time (base-1))

as base (n+1)/2 .

For that you need a level of abstraction/simplification. Keep-it-simple.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM