0234. Palindrome Linked List (E)

Palindrome Linked List (E)

题目

Given a singly linked list, determine if it is a palindrome.

Example 1:

Input: 1->2
Output: false

Example 2:

Input: 1->2->2->1
Output: true

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


题意

判断一个链表的值是否构成回文。

思路

最简单的方法是遍历一遍链表将所有值存到数组中,再对数组进行处理。也可以用栈保存数值,利用栈的性质,出栈顺序即为链表的逆序遍历,只要再遍历一遍链表与出栈相比即可。

对上述方法的优化:利用快慢指针找到链表的中间结点,在此过程中将链表前半部分的值依次压入栈中,接着将慢指针继续向尾结点移动,同时不断出栈进行比较(出栈的值即为前半部分值得逆序)。

(O(1))空间的方法:先利用快慢指针找到链表的中间结点,再将后半部分链表逆置,遍历比较逆置后的链表和前半部分链表即可。


代码实现

Java

栈1

class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) {
            return true;
        }

        ListNode pointer = head;
        Deque<Integer> stack = new ArrayDeque<>();
        
        while (pointer != null) {
            stack.push(pointer.val);
            pointer = pointer.next;
        }
        
        pointer = head;
        
        while (pointer != null) {
            if (pointer.val != stack.pop()) {
                return false;
            }
            pointer = pointer.next;
        }
        
        return true;
    }
}

栈2

class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) {
            return true;
        }
        
        ListNode slow = head;
        ListNode fast = head;
        Deque<Integer> stack = new ArrayDeque<>();

        stack.push(slow.val);
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            stack.push(slow.val);
        }

        if (fast.next == null) {
            stack.pop();
        }

        while (slow.next != null) {
            slow = slow.next;
            if (stack.pop() != slow.val) {
                return false;
            }
        }

        return true;
    }
} 

逆置链表

class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) {
            return true;
        }
        
        ListNode slow = head;
        ListNode fast = head;

        while(fast.next!=null&&fast.next.next!=null){
            fast = fast.next.next;
            slow = slow.next;
        }

        // 标记找到的中间结点(实际为前半部分的最后一个结点),并断开前后链表
        ListNode mid = slow;
        slow = slow.next;
        mid.next = null;
        
        // 逆置后半部分链表
        while (slow != null) {
            ListNode temp = slow.next;
            slow.next = mid.next;
            mid.next = slow;
            slow = temp;
        }
        
        ListNode firstHalf = head;
        ListNode secondHalf = mid.next;

        // 比较前后部分链表
        while (secondHalf != null) {
            if (firstHalf.val != secondHalf.val) {
                return false;
            }
            firstHalf = firstHalf.next;
            secondHalf = secondHalf.next;
        }

        return true;
    }
}

JavaScript

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var isPalindrome = function (head) {
  const dummy = new ListNode()
  let slow = head, fast = head

  while (fast && fast.next) {
    const tmp = slow.next
    fast = fast.next.next
    slow.next = dummy.next
    dummy.next = slow
    slow = tmp
  }

  let A = dummy.next, B = fast ? slow.next : slow

  while (A) {
    if (A.val !== B.val) return false
    A = A.next
    B = B.next
  }

  return true
}
原文地址:https://www.cnblogs.com/mapoos/p/14607285.html