Это поодиночке связанный список палиндромом?


Я решил этот вопрос на Leetcode: https://leetcode.com/problems/palindrome-linked-list/description/. Я преобразования узлов в ArrayList и мне интересно, если это обман? Кроме этого, как я могу оптимизировать это решение:

public class PalindromeLinkedList {

    public static void main(String[] args) {
        ListNode node = new ListNode(0);
        node.next = new ListNode(0);
        //node.next.next = new ListNode(1);
        //node.next.next.next = new ListNode(1);

        ArrayList firstHalf = new ArrayList();
        ArrayList secondHalf = new ArrayList();

        int count = 0;

        ListNode counterNode = node;
        while(counterNode != null) {
            count++;
            counterNode = counterNode.next;
        }

        int middle = count/2;
        boolean middleIgnored = count%2 != 0;
        for(int i = 0; i < middle; i++) {
            firstHalf.add(node.val);
            node = node.next;
        }

        if(middleIgnored) {
            node = node.next;
            System.out.println("middle ignored");
        }

        for(int i = middle + 1; node != null; i++) {
            secondHalf.add(node.val);
            node = node.next;
        }

        Collections.reverse(secondHalf);
        boolean isPalindrome = firstHalf.equals(secondHalf);

        System.out.println("first half: " + firstHalf);
        System.out.println("\nsecond half: " + secondHalf);
        System.out.println("\npalindrome? " + isPalindrome);

    }

}

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}


209
0
задан 4 февраля 2018 в 11:02 Источник Поделиться
Комментарии
1 ответ

LeetCode, кажется, стресс, подготовка к техническому интервью, я считаю целесообразным начать набрасывать самая простая вещь, которая могла сделать (я беру на себя смелость заменить первоначально последнее слово работа).
Вещи мне нравится ваш подход:


  • концептуально простой и чистый:
    сравнивая первую и последнюю половину с одним вспять


    • опираясь на поддержку выполнения в среде выбор
      для сравнения и разворот


Я вообще не считаю преобразование данных для облегчения обработки cheating, если он явно нарушает часть задач описание.
Вещи, которые я не люблю (это далеко, вы видели) о выполнении (указанного подхода):


  • отсутствуют комментарии документа


    • например, об известных недостатков:
      с помощью О(N) дополнительное пространство для удобства, а не необходимость


  • не определив явного сказуемого isPalindrome()

  • преобразование более чем одной части связанного списка отдельно


    • используя повторяющегося кода (это может быть целесообразно в интервью параметр, если прокомментировал (желательно в коде скетча, тоже))


  • объявления Listдля чего они (реализация класса), а не какой пользы они (интерфейс)

Дать ему попробовать:

/** Checks a home-grown linked list
* for <i>palindrome</i> using linear additional space.
* @param node the first node of the list to check, or <code>null

* @вернуть порядок значений в списке
* начиная с node остается неизменным при реверсировании
*/// сравниваем первый тайм, чтобы переломить второй половины
статический логический isPalindrome(конечный узел ListNode) {
окончательный список товары = новый Java.утиль.Класса ArrayList<>();

для (ListNode Н = узел ; Н != нуль; н = н.далее)
элементы.добавить(Н.вал);

тип int количество = элементы.размер(),
средний = сумма/2; // средний элемент подсписка ни на нечетное количество
окончательный список хвост = элементы.подсписок(считай-средний, граф);
Ява.утиль.Коллекции.реверс(решка);
возвращение графа < 2 ||
элементы.подсписок(0, средний).равна(хвост);
}
/** Создает узел списка из значений & отпечатки результате isPalindrome() */
статический недействительным checkNodeList(строковых значений) {
Узел ListNode, Н = узел = новый ListNode(42); // фиктивный
для (байт с: значения.метод getbytes())
н = н.следующий = Новый ListNode(с);
узел = Узел.далее; // пропустить пустышки
Системы.из.метод println("палиндром(" + значения
+ "): "+ isPalindrome(узел));
}
общественности статической силы основных(string[] аргументы) {
checkNodeList("");
checkNodeList("?");
checkNodeList("!!");
checkNodeList("codedoc");
checkNodeList("codedoC");
checkNodeList("cOdedoc");
checkNodeList("Maddam");
checkNodeList("maddam");
checkNodeList("madDam");
}

[optimizing] this solution - Я не могу сделать подход или код понятнее.
LeetCode следовать дальше: может ли единое решение достичь o(n) времени и O(1) пространство?:
Я знаю, как сделать это изменение входного сигнала, я сомневаюсь, что это можно сделать без.
Есть много способов кожи кошки, думал, как легко было бы с помощью Python, я дал поворачивая ListNodeв ListС попробовать, с петлей сжимая и дозорные бросили в:

/** Checks a home-grown linked <code>List
* для палиндром , используя постоянное дополнительное пространство.
*
Временно изменяет список, начиная с node.
* @парам узлов nullили первого узла
* List для проверки
* @вернуть порядок значений в List
* начиная с node остается неизменным при реверсировании
*/
статический логический isPalindrome(конечный узел ListNode) {
если (нуль == узел)
возвратите True;
ListNode
последний, // траверсами список два шага/поворота, останавливается на последнем узле
средний, // середине списка уже пройденный в прошлом
обратная = нуль, // реверс первой половине
медленно = средняя = последняя = узел;
// джем "подсчет" и списанием первой половине
для (ListNode далее ; ; последнее = далее.следующий) {
следующий = последний.далее;
средний = медленно.далее;
если (нуль == следующий)
перерыв;
медленно.следующий = отменено;
обратная = медленный;
медленно = средняя;
если (нуль == далее.следующий) {
последний = следующий;
перерыв;
}
}
если (нуль == отменено)
возвратите True;
логическое mayBePalindrome = последний.Валь == узел.вал;
если (mayBePalindrome) {
последние.Валь = ~узел.вал; // включить в Сентинел
// джем "проверить" и восстановление первой половины; один сравнение
время (вспять.Вэл == средний.Валь) {
ListNode Н = вспять.далее;
обратная.следующий = медленно;
медленно = отменено;
обратная = Н;
средний = средний.далее;
}
mayBePalindrome &= средний == последний;
последние.Валь = узел.вал; // восстановить
}
а (значение null != отменено) {
ListNode Н = вспять.далее;
обратная.следующий = медленно;
медленно = отменено;
обратная = Н;
}
возвращение isPalindrome;
}

/** Результат печати isPalindrome() */
статической проверки недействительными(строку инициализации) {
ListNode узел = нуль == инит
? нуль : новый ListNode(инит, нуль);
Системы.из.код println("палиндром(" + узел
+ "): "+ isPalindrome(узел));
}

общественности статической силы основных(string[] аргументы) {
проверьте(ноль);
проверить("'");
проверить("СС");
проверить("codedoc");
проверить("codedoC");
проверить("cOdedoc");
проверить("Maddam");
проверить("maddam");
проверить("madDam");
}

/** Поодиночке-связанный список узлов классе укрепили некоторые для поддержки
* java.util.List итерации. */
статические ListNode классе расширяется Java.утиль.AbstractList
реализует список
{
инт вал;
ListNode далее;
ListNode(тип int х) { Вэл = х; }
ListNode(тип int х, ListNode Н) { Вэл = х; следующий = Н; }
ListNode(строку инициализации, ListNode Н) {
следующий = Н;
если (значение null != инит && 0 < инит.длина()) {
Вэл = инит.используя метод charat(0);
если (1 <инит.длина())
следующий = Новый ListNode(первонач.подстрока(1), н);
}
}
@Переопределить
общественное целое число получить(индекс типа int) {
если (0 == индекс)
возврат вал;
если (индекс <0)
бросить новый IllegalArgumentException (индекс" <0");
если (нуль == следующий)
бросить новый IllegalArgumentException("размер <= индекс");
вернуться в следующем.вам(индекс-1);
}
@Переопределить
размер государственной инт() { возвращать значение null == следующий ? 1 : 1 + далее.размер(); }
@Переопределить
общественные итератора итератор() {
возвращает новый итератор() {
ListNode глава = ListNode.этого;
@Переопределить
общественная логическое hasNext() { возвращать значение null != голову; }
@Переопределить
общественное целое число следующий() {
инт в = голову.вал;
голова = Голова.далее;
вернуться в;
}
};
}
}

1
ответ дан 6 февраля 2018 в 11:02 Источник Поделиться