题目:
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?
解释:
判断一个;链表是不是回文,但是链表的指针并不能翻转,怎么办呢/
利用快慢指针先找到中间的位置(假设链表长度为n
,则slow指向的是n/2+1
(index从1开始),也就是后半段的 第一个结点),把链表从中间位置开始翻转,再两个指针,一个指向mid一个指向head,开始遍历,如果每个值都一样的话说明是回文。需要考虑链表的长度是奇数或者偶数的情况。
额,当然也可以把链表的元素保存到一个数组中,再判断是不是回文,但是这样的话空间复杂度就不是 O(1)了
python代码:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if not head or not head.next:
return True
slow,fast=head,head
middle_pre=slow
while fast and fast.next:
middle_pre=slow
slow=slow.next
fast=fast.next.next
#middle_pre保存第一部分的最后一个结点
p=middle_pre.next
cur_pre=None
while p:
cur_next=p.next
p.next=cur_pre
cur_pre=p
p=cur_next
middle_pre.next=cur_pre
p_middle=middle_pre.next
p_head=head
while p_head!=middle_pre.next:
if p_head.val!=p_middle.val:
return False
p_head=p_head.next
p_middle=p_middle.next
return True
c++代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (!head ||!head->next)
return true;
ListNode *fast=head,*slow=head;
//middle_pre指向前半段的最后一个元素
ListNode *middle_pre=slow;
while(fast &&fast->next)
{
middle_pre=slow;
slow=slow->next;
fast=fast->next->next;
}
//原地翻转后半部分链表的工作指针
ListNode*cur=middle_pre->next;
ListNode*cur_pre=NULL;
//下面是原地翻转单链表的经典写法
while(cur)
{
ListNode*cur_next=cur->next;
cur->next=cur_pre;
cur_pre=cur;
cur=cur_next;
}
//此时,cur_pre保存翻转后的链表的头结点,这里是合并
middle_pre->next=cur_pre;
//接下来是比较,注意,后半段的元素有可能比前半段的元素多一个
//所以while循环的第一个条件是必须的
ListNode* p_head=head;
ListNode* p_middle=cur_pre;
while(p_head!=middle_pre->next)
{
if(p_head->val!=p_middle->val)
return false;
p_head=p_head->next;
p_middle=p_middle->next;
}
return true;
}
};
总结:
注意最后比较的时候的判断条件只有一个即可,因为后半段的个数肯定>=前半段个数。