Наименьшее число палиндромов больше N

#java #palindrome

#java #палиндром

Вопрос:

Для заданного положительного целого числа N, состоящего не более чем из 1000000 цифр, запишите значение наименьшего палиндрома, большего N, для вывода.

Вот мой код:

 public class Palin {

    public static String reverseString(String s) {
        String newS = "";
        for(int i = s.length() - 1; i >= 0; i--)
            newS  = s.charAt(i);
        return newS;
    }

    public static String getPalin(String s) {
        int lth = s.length();

        String left = "", mid = "", right = "", newS = "";
        if(lth % 2 != 0) {
            left = s.substring(0, lth / 2);
            mid = s.substring(lth / 2, lth / 2   1);
            right = reverseString(left);

            newS = left   mid   right;

            if(s.compareTo(newS) < 0) return newS;
            else {
                int temp = Integer.parseInt(mid);
                temp  ;
                mid = Integer.toString(temp);
                newS = left   mid   right;
                return newS;
            }
        }
        else {
            left = s.substring(0, lth / 2 - 1);
            mid = s.substring(lth / 2 - 1, lth / 2);
            right = reverseString(left);

            newS = left   mid   mid   right;
            if(s.compareTo(newS) < 0) return newS;
            else {
                int temp = Integer.parseInt(mid);
                temp  ;
                mid = Integer.toString(temp);
                newS = left   mid   mid   right;
                return newS;
            }
        }
    }

    public static void main(String[] args) throws java.lang.Exception {
        Scanner input = new Scanner(System.in);
        //Scanner input = new Scanner(System.in);

        int k = input.nextInt();
        String[] s = new String[k];

        for(int i = 0; i < k; i  ) {
            s[i] = input.next();
        }

        for(int i = 0; i < k; i  ) {
            System.out.println(getPalin(s[i]));
        }
    }
}
  

Моя идея заключается в использовании строкового представления для числа. Я делю эту строку на 2 части, меняю первую часть и переворачиваю ее для второй части. Я думаю, что мое решение правильное, но оно недостаточно быстрое. Мне нужен более эффективный алгоритм.
Спасибо

Комментарии:

1. Ваш reverseString неэффективен. Используйте StringBuilder , чтобы перевернуть строку : new StringBuilder(str).reverse().toString()

2. Если ваш код работает не в том месте, попробуйте codereview.stackexchange.com вместо

3. @Eran Спасибо за предложение. Можете ли вы рассказать мне, как работает метод reverse() ??

4. @Puskin вы можете посмотреть на реализацию StringBuilder (или, на самом деле, AbstractStringBuilder). Оно переворачивает массив символов.

5. @Eran: да, и я хочу знать, как перевернуть массив, потому что я думаю, что лучше всего поменять местами 2 элемента 1 — n, 2 — (n-1), .. и так далее.

Ответ №1:

ОТРЕДАКТИРОВАНО
Поскольку вы сказали, что:

Для заданного положительного целого числа N, состоящего не более 1000000 цифр

Мое предыдущее решение не будет работать, поскольку я преобразовал их в int и int не может вместить 1000000 цифр. Таким образом, я разработал новый подход, подход, который не требует преобразования строки в int.

Обратитесь к коду и комментарию ниже для получения подробной информации.

код:

 package main;

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // Scanner input = new Scanner(System.in);

        int k = Integer.parseInt(input.nextLine());
        String[] s = new String[k];

        for (int i = 0; i < k; i  ) {
            s[i] = input.nextLine();
        }

        for (int i = 0; i < k; i  ) {
            System.out.println(getPalin(s[i]));
        }

        input.close();

    }

    public static String getPalin(String s) {
        // initialize the result to "" since if input is 1 digit, nothing is printed
        String result = "";

        // if input is greater than 1000000 digits
        if (s.length() >= 1000000) {
            // return the highest palindrome less than 1000000
            result = "999999";
        } else if (s.length() > 1) {
            // get the middle index of the string
            int mid = s.length() % 2 == 0 ? s.length() / 2 : (s.length() / 2)   1;

            // get the left part of the string
            String leftPart = getPalindrome(s.substring(0, mid));

            if (s.length() % 2 == 0) {
                // attach the left part and the reverse left part
                result = leftPart   new StringBuilder(leftPart).reverse().toString();
            } else {
                // attach the left part and the reverse left part excluding the middle digit
                result = leftPart
                          new StringBuilder(leftPart.substring(0, leftPart.length() - 1)).reverse().toString();
            }

            // check if the new result greater than 1000000 digits
            if (result.length() >= 1000000) {
                // return the highest palindrome less than 1000000
                result = "999999";
            }
        }
        return resu<
    }

    public static String getPalindrome(String param) {
        String result = "";

        // iterate through the string from last index until index 0
        for (int i = param.length() - 1; i >= 0; i--) {
            // get the char at index i
            char c = param.charAt(i);

            /*
             * increment char since the next palindrome is the current digit   1. Example:
             * User input is 121, then param will be 12 so the next is 13
             */
            c  ;

            /*
             * check if the current character is greater than '9', which means it is not a
             * digit after incrementing
             */
            if (c > '9') {
                // set the current char to 0
                c = '0';
                // check if index is at index 0
                if (i - 1 < 0) {
                    // if at index 0 then add '1' at start
                    result = '1'   resu<
                } else {
                    // if not then append c at result
                    result = result   c;
                }
            } else {
                // check if index is at index 0
                if (i - 1 < 0) {
                    // if not then prepend c at result
                    result = c   resu<
                } else {
                    // if not then get the rest of param then append c and result
                    result = param.substring(0, i)   c   resu<
                }
                break;
            }
        }

        return resu<
    }

}
  

Комментарии:

1. Да, ваша идея похожа на меня. Разница заключается только в обратном методе. Я написал функцию, а вы использовали StringBuilder

2. Код @Mark, не содержащий ни одного цикла, не обязательно означает, что его сложность равна O (1). вы должны понимать базовые встроенные функции. например, вы можете использовать встроенный метод sort(), но это также потребует сложности O (nlogn). Здесь вы используете .reverse(), который использует цикл внутри. Надеюсь, вы поняли идею.

3. @AsifRahaman как то, что я сказал «как можно ближе к O (1)». Я не говорил, что это O (1), поскольку я знаю, что мы должны понимать базовые встроенные функции.

4. @Puskin У нас такой же подход, но ваш код не работает при вводе 1 цифры. 🙂

5. @Отметьте тогда, чем это на самом деле отличается? плюс каждый раз, когда вы используете parseInt, который тоже использует цикл!