一开始思考的方式同样是使用Stack,但是这样并没有满足题目要求的利用constant space,所以这里的想法是使用fast runner/slow runner找到Linked List的中间部位,然后反转后面的部分,进而进行比较。一个很好的分析如下图:
注意这里有个小技巧,就是当fast != null的时候将slow指向slow.next,这样可以保证后面反转的部分是比较短的,接下来就可以在while循环中使用slow != null来判断(因为slow比较短)。时间复杂度O(n),空间复杂度O(1),代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverse(ListNode head){
if(head == null) return head;
ListNode prev = null;
while(head != null){
ListNode next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
public boolean isPalindrome(ListNode head) {
if(head == null) return true;
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
if(fast != null) slow = slow.next; // make reversed list the longer one
slow = reverse(slow);
// Compare first half part and reversed part
while(slow != null){
if(slow.val != head.val) return false;
slow = slow.next;
head = head.next;
}
return true;
}
}
知识点:
1. 一个自己经常犯的错误是在使用while循环的Linked List相关问题中,忘记将指针移向next,从而造成死循环
2. fast runner/slow runner
3. reverse linked list