回文链表
leetcode地址:
https://leetcode.com/problems/palindrome-linked-list/description/
描述:
Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2 Output: false
Example 2:
Input: 1->2->2->1 Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
要求时间复杂度O(n), 空间复杂度O(1)
解题分析:
这题的主要思路就是把链表分割,然后把右半部分反转,难点就在于分割,使用快慢指针,重点在于快指针走到尾部时的边界条件的处理需要分为偶数个还是奇数个情况,
如下图:
可见,无论是奇数个元素还是偶数个元素的情况,当fast指针走到最后时,slow指针的下一个元素都是右半部分链表的开始,有了这个结论,我们就可以开始写代码了,
代码:
public boolean isPalindrome(ListNode head) {
if (null == head) {
return true;
}
// 切分链表
ListNode fast = head, slow = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode right = slow.next;
slow.next = null;
right = reverse(right);
while (right != null && head != null) {
if (right.val != head.val) {
return false;
}
right = right.next;
head = head.next;
}
return true;
}
public ListNode reverse(ListNode list) {
ListNode newHead = null;
while (list != null) {
ListNode next=list.next;
list.next = newHead;
newHead = list;
list = next;
}
return newHead;
}
显然,我们只是遍历了有限次的链表,因此时间复杂度是O(n);另外由于只是对链表进行反转,遍历等操作,并没有创建新的节点,所以占用空间是个常量,因此空间复杂度是O(1)