题目描述

// 234. 回文链表
// 请判断一个链表是否为回文链表。
题解
// 数组辅助法
// 将链表中所有元素放进数组list中,之后设置左右指针l和r,循环令左指针右移,
// 右指针左移,令左右指针遍历的元素进行比对,如果不相等则直接返回false,
// 相等则继续移动,循环结束之后返回true。
// 执行用时:14 ms, 在所有 Java 提交中击败了13.86%的用户
// 内存消耗:50.9 MB, 在所有 Java 提交中击败了21.89%的用户
class Solution {
public boolean isPalindrome(ListNode head) {
List<Integer> list = new ArrayList<>();
ListNode cur = head;
while (cur != null) {
list.add(cur.val);
cur = cur.next;
}
int l = 0;
int r = list.size() - 1;
while (l <= r) {
if (!list.get(l).equals(list.get(r)))
return false;
l++;
r--;
}
return true;
}
}
// 找链表中点 + 链表反转
// 还记得【Leetcode】876. 链表的中间结点 和 【Leetcode】206. 反转链表,
// 我们可以使用876题先找链表中点,我们在这里不要靠右的点,而是要靠左的点,
// 所以要将快慢针的快针初始化到head的next,来进行快慢针,找到中点mid之后。
// 取mid.next之后的链表,做链表反转。
// 反转链表之后,mid指针会成为反转链表的头结点,记为rightHead。
// 那我们就有没反转的左半部分链表记为leftHead,和反转之后的右半部分链表
// rightHead,双指针循环移动,从leftHead和rightHead开始出发,然后比对双
// 指针的遍历元素,如果不相同,直接返回false,如果遍历完了,直接返回true
//
// 比如目标链表为:
//leftH
// 1 -> 2 -> 3 -> 3 -> 2 -> 1
//
// 找到中点mid有:
//leftH mid
// 1 -> 2 -> 3 -> 3 -> 2 -> 1
//
// 翻转mid.next之后的链表有:
//leftH mid
// 1 -> 2 -> 3 3 -> 2 -> 1
//
//leftH mid rightH
// 1 -> 2 -> 3 3 <- 2 <- 1
//
// 之后leftHead和rightHead一起双指针移动,如果是回文链表,指针元素一定相等,
// 否则就不是回文链表。
//
// 执行用时:5 ms, 在所有 Java 提交中击败了58.54%的用户
// 内存消耗:48.3 MB, 在所有 Java 提交中击败了57.95%的用户
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode cur = head.next;
ListNode mid = head;
while (cur != null && cur.next != null) {
cur = cur.next.next;
mid = mid.next;
}
ListNode rightHead = reverseListNode(mid.next);
ListNode leftHead = head;
while (leftHead != null && rightHead != null) {
if (leftHead.val != rightHead.val)
return false;
leftHead = leftHead.next;
rightHead = rightHead.next;
}
return true;
}
public ListNode reverseListNode(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode pre = head;
ListNode mid = head.next;
ListNode cur = head.next.next;
pre.next = null;
mid.next = pre;
while (cur != null) {
pre = mid;
mid = cur;
cur = cur.next;
mid.next = pre;
}
return mid;
}
}