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
}