Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
思路1:遍历一边链表,把它放到数组或VECTOR里,转化为字符串的回文判断。
但是时间复杂度和空间复杂度都是O(n)。
class Solution {
public:
bool isPalindrome(ListNode* head) {
vector<int> v;
while(head){
v.push_back(head->val);
head=head->next;
}
for(int i=0,j=v.size()-1;i<j;i++,j--){
if(v[i]!=v[j])
return false;
}
return true;
}
};
思路二:先找到链表的中间的那个点,把链表分割成2个部分。
这个方法可以用判断链表是否有环的思想,设置两个指针,
一个每次向前移动一步,一个每次移动二步。
然后将链表的一个部分反转,再依次进行比较。
/**
* 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 *t1=head,*t2=head;
while(t2&&t2->next){
t1=t1->next;
t2=t2->next->next;
}
if(t2){
t1=t1->next;
}
t1=reverseList(t1);
while(t1){
if(t1->val!=head->val)
return false;
t1=t1->next;
head=head->next;
}
return true;
}
ListNode* reverseList(ListNode* head){
if(!head||!head->next)return head;
ListNode *t1=head,*t2=head->next;
t1->next=NULL;
while(t2){
ListNode *t3=t2->next;
t2->next=t1;
t1=t2;
t2=t3;
}
return t1;//错误点,return head;
}
};
这个题目自己在写反转链表的时候,return的返回值写成了head让我花了好久才找出来了这个BUG。
还写了链表的测试代码。保留下,方便以后调试代码吧。
#include <iostream>
#include<cstring>
#include <vector>
#include <cstdio>
#include <assert.h>
using namespace std;
struct ListNode
{
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode *creatList(int n) {
ListNode head(-1);
ListNode *prev = &head;
int val;
for (int i = 0; i < n; ++i) {
cin >> val ;
prev->next = new ListNode(val);
prev = prev->next;
}
prev->next = NULL;
return head.next;
}
void printList(ListNode*pHead){
if(!pHead)return;
while(pHead){
cout<<pHead->val<<" ";
pHead=pHead->next;
}
cout<<endl;
}
ListNode* reverseList(ListNode* head){
if(!head||!head->next)return head;
ListNode *t1=head,*t2=head->next;
t1->next=NULL;
while(t2){
ListNode *t3=t2->next;
t2->next=t1;
t1=t2;
t2=t3;
}
return head;
}
bool isPalindrome(ListNode* head) {
if(!head||!head->next){
return true;
}
ListNode *t1=head,*t2=head;
while(t2&&t2->next){
t1=t1->next;
t2=t2->next->next;
}
if(t2){
t1=t1->next;
}
t1=reverseList(t1);
while(t1){
if(t1->val!=head->val)
return false;
t1=t1->next;
head=head->next;
}
return true;
}
void destoryList(ListNode* pHead)
{
assert(pHead!=NULL);
ListNode* pNext = pHead->next;
while(pNext != NULL)
{
delete pHead;
pHead = pNext;
pNext = pHead->next;
}
delete pHead;
pHead = NULL;
return;
}
int main()
{
ListNode* head = creatList(4);
printf("%d\n",isPalindrome(head));
destoryList(head);
}