实现单链表的对称判定算法

在Y公司的笔试题中遇见了这样一个题目:

 

一个单链表,如何使用O(1)的空间复杂度判定其是否为对称链表,例如A->B->C->T->C->B->A就是一个对称链表。

 

首先最自然的就能想到N^2的算法:

查找1号和最后一个是否相同,再查找2号和倒数第二个。。。查找i和N-i是否相同。

但是这个算法明显不是最优解答。

 

对链表的分析之后可以看出,如果找到中间节点,从中间节点断开链表,反向链表后部的部分,再一起遍历两个链表,这样的算法的时间复杂度一定是N,而反向链表所需要的空间开销也为常数。

 

代码如下:

  1. #include <iostream>   
  2.   
  3. using namespace std;  
  4.   
  5. struct Node{  
  6.     int data;  
  7.     Node *next;  
  8. };  
  9. Node *head;  
  10.   
  11. int initial()  
  12. {  
  13.     head = new Node;  
  14.     head->data = 0;  
  15.     head->next = NULL;  
  16.     Node *pNode = head;  
  17.     for (int i=1;i<6;++i)  
  18.     {  
  19.         pNode->next = new Node;  
  20.         pNode = pNode->next;  
  21.         pNode->data = i;  
  22.         pNode->next = NULL;  
  23.     }  
  24.     for (int i=5;i>=0;--i)  
  25.     {  
  26.         pNode->next = new Node;  
  27.         pNode = pNode->next;  
  28.         pNode->data = i;  
  29.         pNode->next = NULL;  
  30.     }  
  31.     return 0;  
  32. }  
  33. void deleteList()  
  34. {  
  35.     Node *pNode = head;  
  36.     while(pNode){  
  37.         Node *q = pNode->next;  
  38.         delete pNode;  
  39.         pNode = q;  
  40.     }  
  41. }  
  42.   
  43. void printList(Node *head)  
  44. {  
  45.     Node *pNode = head;  
  46.     while(pNode){  
  47.         cout<<pNode->data<<endl;  
  48.         pNode = pNode->next;  
  49.     }  
  50. }  
  51.   
  52. Node* reverseList(Node *head)  
  53. {  
  54.     Node *pNode = head->next,  
  55.              *pNext = NULL;  
  56.     head->next = NULL;  
  57.     while (pNode)  
  58.     {  
  59.         pNext = pNode->next;  
  60.         pNode->next = head;  
  61.         head = pNode;  
  62.         pNode = pNext;  
  63.     }  
  64.     return head;  
  65. }  
  66.   
  67. bool yahooList()  
  68. {  
  69.     int len = 0;  
  70.     Node *pNode = head;  
  71.       
  72.     //get length   
  73.     while (pNode)  
  74.     {  
  75.         ++len;  
  76.         pNode = pNode->next;  
  77.     }  
  78.       
  79.     if (1 == len)  
  80.     {  
  81.         return true;  
  82.     }  
  83.   
  84.     //找中点,如果是奇数个则指向中点的下一个元素   
  85.     bool bOdd = len & 0x00000001;//odd num delete middle number   
  86.     int mid = len>>1;  
  87.     int i = 0;  
  88.     pNode = head;  
  89.     while(i++ != mid)  
  90.         pNode = pNode->next;  
  91.   
  92.     if (bOdd)  
  93.         pNode = pNode->next;  
  94.   
  95.     Node *pOther = reverseList(pNode);  
  96. #ifdef _DEBUG   
  97.     cout<<"the reverse list is:"<<endl;  
  98.     printList(pOther);  
  99. #endif // _DEBUG   
  100.   
  101.     //顺序比较   
  102.     pNode = head;  
  103.     while (pOther && pNode)  
  104.     {  
  105.         if (pOther->data != pNode->data)  
  106.         {  
  107.             return false;  
  108.         }  
  109.         pOther = pOther->next;  
  110.         pNode = pNode->next;  
  111.     }  
  112.     return true;  
  113. }  
  114.   
  115. int main()  
  116. {  
  117.     initial();  
  118.     printList(head);  
  119.     cout<<yahooList()<<endl;  
  120.     return 0;  
  121. }  
posted @ 2012-06-25 14:20  springbarley  阅读(446)  评论(0)    收藏  举报