链表回文结构判断较简单的做法是利用栈存储链表逆序序列,之后与列表正序序列 比较,如果一致,则说明是回文结构;这样时间复杂度O(n),空间复杂度O(n),下面这种方法时间复杂度O(n),空间复杂度O(1),其基本思路是把链表右半部分反转,然后同时从原始链表的首尾同时向中间遍历,比较每一个位置对应的value,代码如下:
struct ListNode
{
int value;
ListNode* m_pNext;
};
bool isPalindrome(ListNode* head)
{
if ( !head || !head->m_pNext )
{
return true;
}
//找到中间节点
ListNode* node0,*node1;
node0 = node1 = head;
while ( node1->m_pNext && node1->m_pNext->m_pNext )
{
node0 = node0->m_pNext;//中间节点
node1 = node1->m_pNext->m_pNext;
}
//反转右半部分链表
node1 = node0->m_pNext;//右半部分的起始节点
node0->m_pNext = NULL;//中间node指向空 作为比较终止条件
ListNode* pre = node0;
ListNode* temp = NULL;
while ( node1 )
{
temp = node1->m_pNext;
node1->m_pNext = pre;
pre = node1;
node1 = temp;
}
//保存链表尾节点 之后恢复链表使用
ListNode* tail = pre;
node0 = head;
//比较
bool res = true;
while ( pre && node0)
{
if ( pre->value != node0->value )
{
res = false;
break;
}
pre = pre->m_pNext;
node0 = node0->m_pNext;
}
//恢复链表
pre = NULL;
while ( tail )
{
temp = tail->m_pNext;
tail->m_pNext = pre;
pre= tail;
tail = temp;
}
return res;
}
int main()
{
for ( int i = 0; i < 6; i++ )
{
list[i] = ListNode();
if ( i<5 )
{
list[i].m_pNext = &list[i+1];
}
else
list[i].m_pNext = NULL;
}
list[0].value = 1;
list[1].value = 2;
list[2].value = 3;
list[3].value = 3;
list[4].value = 2;
list[5].value = 2;
cout<<bool(isPalindrome(list))<<endl;
ListNode* tempNode = list;
while ( tempNode )
{
cout<<tempNode->value<<" ";
tempNode = tempNode->m_pNext;
}
return 1;
}