这道题很有意思,你能在O(1) space,O(n) time约束下做出来吗?
让我们来一步一步观察,思考。
回文,那么意味着是轴对称的,想到用比较最左端和最右端的方法,可是这在单链表上是根本没法做的,除非是双向链表,但题目也不允许修改数据结构啊,所以不可行。再想想,把链表逆转吧,但是逆转之后怎么办?失去了比较对象啊。再想想,那逆转一半如何?如果是回文的话,前半段和后半段就必须是一样的。好,这方法靠谱,下一步是找到中间的结点,如果结点数是奇数,则直接返回中间结点;如果为偶数,应该返回靠右的结点。这个求中间结点的代码为:
ListNode * getMiddle(ListNode *head) {
ListNode *p1 = head,*p2 = head;
while (p2 && p2->next) {
p1 = p1->next;
p2 = p2->next->next;
}
return p1;
}
好的,然后链表逆转的算法。
ListNode * reverseLink(ListNode *head) {
ListNode *p1 = nullptr;
ListNode *p2 = head;
while(p2){
ListNode *t = p2->next;
p2->next = p1;
p1 = p2;
p2 = t;
}
return p1;
}
然后,这道题就可以这么写。
bool isPalindrome(ListNode *head){
ListNode *mid = getMiddle(head);
ListNode *right = reverseLink(mid);
for(;head && right; head=head->next,right=right->next) {
if(head->val != right->val)
return false;
}
return true;
}
嘻嘻。