题目
Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2Output: false
Example 2:
Input: 1->2->2->1Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
题意
判断一个链表的值是否构成回文。
思路
最简单的方法是遍历一遍链表将所有值存到数组中,再对数组进行处理。也可以用栈保存数值,利用栈的性质,出栈顺序即为链表的逆序遍历,只要再遍历一遍链表与出栈相比即可。
对上述方法的优化:利用快慢指针找到链表的中间结点,在此过程中将链表前半部分的值依次压入栈中,接着将慢指针继续向尾结点移动,同时不断出栈进行比较(出栈的值即为前半部分值得逆序)。
#card=math&code=O%281%29)空间的方法:先利用快慢指针找到链表的中间结点,再将后半部分链表逆置,遍历比较逆置后的链表和前半部分链表即可。
代码实现
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 = headwhile (fast && fast.next) {const tmp = slow.nextfast = fast.next.nextslow.next = dummy.nextdummy.next = slowslow = tmp}let A = dummy.next, B = fast ? slow.next : slowwhile (A) {if (A.val !== B.val) return falseA = A.nextB = B.next}return true}
