Check if a Linked List Is a Palindrome
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ number of nodes in head ≤ 500 - ◆
-100 ≤ node value ≤ 100
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public boolean isPalindrome(Node head) { |
| 3 | if (head == null || head.next == null) { |
| 4 | return true; |
| 5 | } |
| 6 | Node slow = head, fast = head; |
| 7 | while (fast != null && fast.next != null) { |
| 8 | slow = slow.next; |
| 9 | fast = fast.next.next; |
| 10 | } |
| 11 | Node prev = null; |
| 12 | Node curr = slow; |
| 13 | while (curr != null) { |
| 14 | Node nextNode = curr.next; |
| 15 | curr.next = prev; |
| 16 | prev = curr; |
| 17 | curr = nextNode; |
| 18 | } |
| 19 | Node p1 = head, p2 = prev; |
| 20 | while (p2 != null) { |
| 21 | if (p1.val != p2.val) { |
| 22 | return false; |
| 23 | } |
| 24 | p1 = p1.next; |
| 25 | p2 = p2.next; |
| 26 | } |
| 27 | return true; |
| 28 | } |
| 29 | } |
| 30 |
1More than one node — the real check has to run.
Approach & Solutions
Brute Force — Copy to an Array, Two-Pointer Check
GoodCopy every node's value into an array, then check whether that array reads the same forwards and backwards using two pointers closing in from both ends. Correct and simple, but it costs an array the size of the whole list — the optimal solution gets the same answer without allocating anything proportional to n.
O(n)O(n)1// Node definition used in this problem:
2// class Node {
3// int val;
4// Node next;
5// }
6
7class Solution {
8 public boolean isPalindrome(Node head) {
9 List<Integer> vals = new ArrayList<>();
10 Node curr = head;
11 while (curr != null) {
12 vals.add(curr.val);
13 curr = curr.next;
14 }
15 int lo = 0, hi = vals.size() - 1;
16 while (lo < hi) {
17 if (!vals.get(lo).equals(vals.get(hi))) {
18 return false;
19 }
20 lo++;
21 hi--;
22 }
23 return true;
24 }
25}Optimal — Find the Middle, Reverse the Second Half, Compare
OptimalFind the middle with slow/fast pointers, reverse the second half in place (the exact same relink primitive used to reverse any run of nodes), then walk two pointers outward from the middle — one over the untouched front half, one over the freshly-reversed second half — comparing values as they go. If every pair matches, it's a palindrome. The list ends up with its second half reversed, but that's a fine trade for doing the whole check in O(1) extra space.
O(n)O(1)1// Node definition used in this problem:
2// class Node {
3// int val;
4// Node next;
5// }
6
7class Solution {
8 public boolean isPalindrome(Node head) {
9 if (head == null || head.next == null) {
10 return true;
11 }
12 Node slow = head, fast = head;
13 while (fast != null && fast.next != null) {
14 slow = slow.next;
15 fast = fast.next.next;
16 }
17 Node prev = null;
18 Node curr = slow;
19 while (curr != null) {
20 Node nextNode = curr.next;
21 curr.next = prev;
22 prev = curr;
23 curr = nextNode;
24 }
25 Node p1 = head, p2 = prev;
26 while (p2 != null) {
27 if (p1.val != p2.val) {
28 return false;
29 }
30 p1 = p1.next;
31 p2 = p2.next;
32 }
33 return true;
34 }
35}