题目描述
请编写一个函数,检查链表是否为回文。
给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试样例:
{1,2,3,2,1}
请编写一个函数,检查链表是否为回文。
给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试样例:
{1,2,3,2,1}
返回:true
{1,2,3,2,3}返回:false
#include<iostream>
using namespace std;
#include<stack>
struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x):val(x),next(NULL) { }
};
// 方式一:用一个辅助栈,时间复杂度O(n),空间复杂度O(n)
/*bool IsPalindrome(ListNode *pHead)
{
if(pHead == NULL || pHead->next == NULL)
return true;
stack<ListNode*> s;
ListNode *pCur = pHead;
while (pCur)
{
s.push(pCur);
pCur = pCur->next;
}
pCur = pHead;
while (pCur)
{
ListNode *ptemp = s.top();
if(pCur->val != ptemp->val)
return false;
pCur = pCur->next;
s.pop();
}
return true;
}
*/
//方式二,将链表的后半部分逆置判断,时间复杂度O(n),空间复杂度O(1).
void Reverse(ListNode *&pHead)
{
if(pHead == NULL || pHead->next == NULL)
return ;
ListNode *pCur = pHead->next;
ListNode *pPre = pHead;
while(pCur)
{
ListNode *pNext = pCur->next;
pCur->next = pPre;
pPre = pCur;
pCur = pNext;
}
pHead->next = NULL;
pHead = pPre;
}
bool IsPalindrome(ListNode *pHead)
{
if (pHead == NULL || pHead->next == NULL)
return true;
ListNode *pSlow = pHead;
ListNode *pFast = pHead->next;
//while循环走完,pslow指向中间节点,如果有偶数个节点的话,pslow指向中间两个节点的前一个节点。
while(pFast && pFast->next)
{
pSlow = pSlow->next;
pFast = pFast->next->next;
}
//逆置后半部分链表
//如1->2->3->2->1 逆置2->1 变成1->2
//如1->2->2->1 逆置2->1 变成1->2
ListNode *pReversehead = pSlow->next;
Reverse(pReversehead);
ListNode *p1 = pReversehead ;
ListNode *p2 = pHead;
//后半部分链表肯定要小于或等于前半部分链表,所以用后半部分链表来判断。
while(p1)
{
if(p1->val != p2->val)
return false;
p1 = p1->next;
p2 = p2->next;
}
//判断完后将链表还原
Reverse(pReversehead);
pSlow->next = pReversehead;
return true;
}
void test()
{
ListNode *p1 = new ListNode(1);
ListNode *p2 = new ListNode(2);
ListNode *p3 = new ListNode(3);
ListNode *p4 = new ListNode(4);
ListNode *p5 = new ListNode(5);
p1->next = p2;
p2->next = p3;
p3->next = p4;
p4->next = p5;
cout << IsPalindrome( p1) <<endl;
}
int main()
{
test();
cout << "hello..."<<endl;
return 0;
}