[LeetCode] 234. Palindrome Linked List

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

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

Example 2:
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?

回文链表。

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

思路

题意是给一个链表,判断是不是回文链表。思路是快慢指针找到链表中点,reverse 后半段,然后比较前半和后半。题目要求不能使用额外空间。

注意代码中找中点的部分,slow 指针需要停在前半部分的最后一个节点。这个细节容易错。

复杂度

时间O(n) - 题目要求
空间O(1) - 题目要求

代码

Java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
// corner case
if (head == null) {
return true;
}
// normal case
ListNode middle = findMiddle(head);
middle.next = reverse(middle.next);
ListNode p1 = head;
ListNode p2 = middle.next;
while (p1 != null && p2 != null) {
if (p1.val != p2.val) {
return false;
}
p1 = p1.next;
p2 = p2.next;
}
return true;
}

// 注意这里找中点的写法,middle会停在左半边的最后一个节点
private ListNode findMiddle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}

private ListNode reverse(ListNode head) {
ListNode pre = null;
while (head != null) {
ListNode next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
}

JavaScript实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function(head) {
if (head === null) return true;
let middle = findMiddle(head);
middle.next = reverse(middle.next);

let p = head;
let q = middle.next;
while (p !== null && q !== null) {
if (p.val !== q.val) {
return false;
}
p = p.next;
q = q.next;
}
return true;
};

var findMiddle = function(head) {
let slow = head;
let fast = head.next;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}

var reverse = function(head) {
let pre = null;
while (head !== null) {
let next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}

相关题目

1
2
3
4
125. Valid Palindrome
234. Palindrome Linked List
680. Valid Palindrome II
2130. Maximum Twin Sum of a Linked List

[LeetCode] 234. Palindrome Linked List
https://shurui91.github.io/posts/209010631.html
Author
Aaron Liu
Posted on
November 10, 2019
Licensed under