Leetcode 234. Palindrome Linked List--判断是否是回文链表,返回中间节点,反转链表

133 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

Given the head of a singly linked list, return true if it is a palindrome.

Example 1:

Input: head = [1,2,2,1]
Output: true

Example 2:

Input: head = [1,2]
Output: false

Constraints:

  • The number of nodes in the list is in the range [1, 105].
  • 0 <= Node.val <= 9

Follow up: Could you do it in O(n) time and O(1) space?

package com.linkedlist;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * @Author you guess
 * @Date 2022/4/4 21:43
 * @Version 1.0
 * @Desc 判断是否是回文链表
 */
public class Leetcode_234_PalindromeLinkedList {
 
 
    /**
     * 方法1
     * T = O(n),S = O(n)
     * <p>
     * Runtime: 17 ms, faster than 33.68% of Java online submissions for Palindrome Linked List.
     * Memory Usage: 107.5 MB, less than 17.29% of Java online submissions for Palindrome Linked List.
     */
    boolean isPalindromeSolution1(ListNode head) {
        //无节点 或 只有 1个节点
        if (head == null || head.next == null) {
            return true;
        }
        //List<ListNode> list = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        while (head != null) {
            list.add(head.val);
            head = head.next;
        }
 
        int front = 0;
        int back = list.size() - 1;
        while (front < back) {
            if (list.get(front) != list.get(back)) {
                return false;
            }
            front++;
            back--;
        }
        return true;
    }
 
 
    /**
     * 方法2
     * T = O(n),S = O(1)
     * 先找到中间的节点,然后把后一半链表反转,再从头、从中间往后比较
     *
     * @param head
     * @return
     */
    boolean isPalindrome(ListNode head) {
        ListNode front = head;
        ListNode half = this.findHalfNode(head);//找到中间节点
        ListNode reverseFront = this.reverseLinkedList(half); // 后半部分反转后的头指针
        while (reverseFront != null) {//reverseFront是先成为null,所以此处不必再写"front != null && "
            if (front.val == reverseFront.val) {
                front = front.next;
                reverseFront = reverseFront.next;
            } else {
                return false;
            }
        }
        return true;//reverseFront==null时,说明遍历到了结尾,front与reverseFront的值都相等,则返回true
    }
 
 
    /**
     * 寻找中间节点
     * 1 2 3 3 2 1 返回第2个 3
     * 1 2 3 2 1 返回第2个 2
     * <p>
     * 共2个节点时,返回第2个节点
     * 共1个节点时,返回null,到下一步reverseLinkedList反转时,也是返回null
     *
     * @param head
     * @return
     */
    ListNode findHalfNode(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
 
        //节点总数为偶数,比如1 2 3 3 2 1
        if (fast == null) return slow;
 
            //节点总数为奇数,比如1 2 3 2 1
        else return slow.next;
    }
 
 
    /**
     * 反转链表
     * 3 2 1 -> 1 2 3
     * Runtime: 6 ms, faster than 73.89% of Java online submissions for Palindrome Linked List.
     * Memory Usage: 97.4 MB, less than 57.01% of Java online submissions for Palindrome Linked List.
     *
     * @param head
     * @return
     */
    ListNode reverseLinkedList(ListNode head) {
        //无节点 或 只有 1个节点
        if (head == null || head.next == null) {
            return head;
        }
 
        ListNode pre = null;
        ListNode nextTemp = null;
        ListNode cur = head;
        while (cur != null) {
            nextTemp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nextTemp;
        }
        return pre;
    }
 
    public static void main(String[] args) {
/*        ListNode node12 = new ListNode(1, null);
        ListNode node22 = new ListNode(2, node12);
        ListNode node32 = new ListNode(3, node22);
        ListNode node42 = new ListNode(4, node32);
        ListNode node41 = new ListNode(4, node42);
        ListNode node31 = new ListNode(3, node41);
        ListNode node21 = new ListNode(2, node31);
        ListNode node11 = new ListNode(1, node21);*/
 
 
        ListNode node12 = new ListNode(1, null);
        ListNode node22 = new ListNode(2, node12);
        ListNode node32 = new ListNode(3, node22);
        ListNode node41 = new ListNode(4, node32);
        ListNode node31 = new ListNode(3, node41);
        ListNode node21 = new ListNode(2, node31);
        ListNode node11 = new ListNode(1, node21);
 
 
        Leetcode_234_PalindromeLinkedList main = new Leetcode_234_PalindromeLinkedList();
 
        System.out.println(main.isPalindrome(node11));
    }
 
 
}

返回中间节点:

end