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

1 2
| 输入:head = [1,2,2,1] 输出:true
|
示例 2:

1 2
| 输入:head = [1,2] 输出:false
|
提示:
- 链表中节点数目在范围
[1, 105] 内
0 <= Node.val <= 9
实现代码
方式一
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ListNode p; public boolean isPalindrome(ListNode head) {
p = head; recursion(head); return p.next == null; }
private ListNode recursion(ListNode head){
if(head == null) { return null; } ListNode lastNode = recursion(head.next); if(lastNode != null && lastNode.val == p.val){ p = p.next; } return head; }
|
时间复杂度
时间组成:
假设n个节点
总的时间:O(n)
空间复杂度
空间组成:
总的空间:O(n)
方式二
栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public boolean isPalindrome(ListNode head) {
ListNode pp = head; Deque<ListNode> deque = new LinkedList<>(); while(head != null){ deque.push(head); head = head.next; } while (!deque.isEmpty()){ ListNode pop = deque.pop(); if(pop.val == pp.val){ pp = pp.next; } } return pp == null; }
|
时间复杂度
时间组成:
总时间:O(n)
空间复杂度
空间组成:
总空间:O(n)
方式三
快慢指针 + 迭代反转
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
| public boolean isPalindrome(ListNode head) {
ListNode slow = head, fast = head; while(fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } slow = reverse(slow); while(slow != null) { if(head.val != slow.val){ return false; } head = head.next; slow = slow.next; } return true; }
private ListNode reverse(ListNode head){
ListNode tmp = null, next; while(head != null){ next = head.next; head.next = tmp; tmp = head; head = next; } return tmp; }
|
时间复杂度
时间组成:
- slow走到中间节点的时间:
O(n/2)
- 反转的时间:
O(n/2)
- 对比的时间:
O(n/2)
总时间:O(n)
空间复杂度
空间组成:
- 快慢指针变量:
O(1)
- 反转方法中的变量:
O(1)
总空间:O(1)