实现单链表的对称判定算法
在Y公司的笔试题中遇见了这样一个题目:
一个单链表,如何使用O(1)的空间复杂度判定其是否为对称链表,例如A->B->C->T->C->B->A就是一个对称链表。
首先最自然的就能想到N^2的算法:
查找1号和最后一个是否相同,再查找2号和倒数第二个。。。查找i和N-i是否相同。
但是这个算法明显不是最优解答。
对链表的分析之后可以看出,如果找到中间节点,从中间节点断开链表,反向链表后部的部分,再一起遍历两个链表,这样的算法的时间复杂度一定是N,而反向链表所需要的空间开销也为常数。
代码如下:
- #include <iostream>
- using namespace std;
- struct Node{
- int data;
- Node *next;
- };
- Node *head;
- int initial()
- {
- head = new Node;
- head->data = 0;
- head->next = NULL;
- Node *pNode = head;
- for (int i=1;i<6;++i)
- {
- pNode->next = new Node;
- pNode = pNode->next;
- pNode->data = i;
- pNode->next = NULL;
- }
- for (int i=5;i>=0;--i)
- {
- pNode->next = new Node;
- pNode = pNode->next;
- pNode->data = i;
- pNode->next = NULL;
- }
- return 0;
- }
- void deleteList()
- {
- Node *pNode = head;
- while(pNode){
- Node *q = pNode->next;
- delete pNode;
- pNode = q;
- }
- }
- void printList(Node *head)
- {
- Node *pNode = head;
- while(pNode){
- cout<<pNode->data<<endl;
- pNode = pNode->next;
- }
- }
- Node* reverseList(Node *head)
- {
- Node *pNode = head->next,
- *pNext = NULL;
- head->next = NULL;
- while (pNode)
- {
- pNext = pNode->next;
- pNode->next = head;
- head = pNode;
- pNode = pNext;
- }
- return head;
- }
- bool yahooList()
- {
- int len = 0;
- Node *pNode = head;
- //get length
- while (pNode)
- {
- ++len;
- pNode = pNode->next;
- }
- if (1 == len)
- {
- return true;
- }
- //找中点,如果是奇数个则指向中点的下一个元素
- bool bOdd = len & 0x00000001;//odd num delete middle number
- int mid = len>>1;
- int i = 0;
- pNode = head;
- while(i++ != mid)
- pNode = pNode->next;
- if (bOdd)
- pNode = pNode->next;
- Node *pOther = reverseList(pNode);
- #ifdef _DEBUG
- cout<<"the reverse list is:"<<endl;
- printList(pOther);
- #endif // _DEBUG
- //顺序比较
- pNode = head;
- while (pOther && pNode)
- {
- if (pOther->data != pNode->data)
- {
- return false;
- }
- pOther = pOther->next;
- pNode = pNode->next;
- }
- return true;
- }
- int main()
- {
- initial();
- printList(head);
- cout<<yahooList()<<endl;
- return 0;
- }
浙公网安备 33010602011771号