鏈表回文判斷(C++)


 
        

題目描述:

對於一個鏈表,請設計一個時間復雜度為O(n),額外空間復雜度為O(1)的算法,判斷其是否為回文結構。
給定一個鏈表的頭指針A,請返回一個bool值,代表其是否為回文結構。保證鏈表長度小於等於900。
測試樣例:
1->2->2->1

返回:true

思路:  
  由於空間復雜度要求為O(1),也就是說臨時占用空間和輸入數據規模無關,因此無法利用數組或者是棧進行判斷。因此先找到中間位置將后半部分指針翻轉,然后兩端分別比較。注意這種方法會修改原鏈表,但是空間復雜度要求為O(1)也只能這么做了。

程序運行流程:
  1、利用快慢指針找到中間的位置(起初均指向頭結點,然后pSlow一次走一步,pFast一次走兩步。注意不需要區分鏈表結點個數是奇數還是偶數);
  2、將后半部分指針翻轉;
  3、最后再進行一次遍歷,一個從前向后,一個從后向前。

下圖是演示圖(分為
鏈表結點個數奇數和偶數兩種情況),當pFast或pFast->next到達尾部(為NULL)時,pSlow正好到達中間位置。其中當鏈表結點個數為偶數時,pFast首先變為NULL;當鏈表結點個數為奇數時,pFast->next首先變為NULL。

  

   

 

 

  

   

代碼:

 

  1 /*
  2 本程序說明:
  3 
  4 時間限制:3秒 空間限制:32768K 熱度指數:8332
  5 本題知識點: 鏈表 棧
  6 
  7 題目描述
  8 對於一個鏈表,請設計一個時間復雜度為O(n),額外空間復雜度為O(1)的算法,判斷其是否為回文結構。
  9 給定一個鏈表的頭指針A,請返回一個bool值,代表其是否為回文結構。保證鏈表長度小於等於900。
 10 測試樣例:
 11 1->2->2->1
 12 返回:true
 13 
 14 */
 15 
 16 #include <iostream>
 17 using namespace std;
 18 
 19 struct ListNode {
 20     int val;
 21     struct ListNode *next;
 22     ListNode(int x) : val(x), next(NULL) {}
 23 };
 24 
 25 //鏈表結點構造
 26 ListNode*  create_list_node(int val)
 27 {
 28     ListNode* pNode = new ListNode(val);
 29     return pNode;
 30 }
 31 //鏈表結點連接
 32 void connect_list_node(ListNode* pCur, ListNode* pNext)
 33 {
 34     pCur->next = pNext;
 35 }
 36 
 37 
 38 
 39 class PalindromeList {
 40 public:
 41     bool chkPalindrome(ListNode* A) {
 42         // write code here
 43         ListNode* pSlow = A;
 44         ListNode* pFast = A;
 45 
 46         while(pFast != NULL && pFast->next != NULL)
 47         {
 48             pSlow = pSlow->next;
 49             pFast = pFast->next->next;
 50         }
 51         //反轉鏈表后半部分指針
 52         ListNode* prev = pSlow;//臨時保存用
 53         pSlow = pSlow->next;
 54         prev->next = NULL;//最中間的點的next置為NULL
 55         while(pSlow != NULL)
 56         {
 57             cout<<pSlow->val<<endl;
 58             ListNode* tmp = pSlow->next;//保存后面的結點
 59             pSlow->next=prev;
 60             prev = pSlow;
 61             pSlow = tmp;
 62         }
 63 
 64         ListNode* pForward = A;//指向頭結點
 65         ListNode* pBackward= prev;//指向鏈表最后一個結點
 66 
 67         while(!(pForward == pBackward || pForward->next == pBackward))
 68         {
 69             if(pForward->val != pBackward->val)
 70                 return false;
 71             pForward = pForward->next;
 72             pBackward = pBackward->next;
 73         }
 74         return true;
 75     }
 76 };
 77 
 78 void test()
 79 {
 80     //創建結點
 81     ListNode* pNode1 = create_list_node(1);
 82     ListNode* pNode2 = create_list_node(1);
 83     ListNode* pNode3 = create_list_node(7);
 84     ListNode* pNode4 = create_list_node(2);
 85     ListNode* pNode5 = create_list_node(7);
 86     ListNode* pNode6 = create_list_node(1);
 87     ListNode* pNode7 = create_list_node(1);
 88 //    ListNode* pNode8 = create_list_node(45);
 89 //    ListNode* pNode9 = create_list_node(-7);
 90 
 91     //連接結點
 92     connect_list_node(pNode1,pNode2);
 93     connect_list_node(pNode2,pNode3);
 94     connect_list_node(pNode3,pNode4);
 95     connect_list_node(pNode4,pNode5);
 96     connect_list_node(pNode5,pNode6);
 97     connect_list_node(pNode6,pNode7);
 98 //    connect_list_node(pNode7,pNode8);
 99 //    connect_list_node(pNode8,pNode9);
100 
101     PalindromeList test;
102 
103     bool flag=test.chkPalindrome(pNode1);
104     cout<<flag<<endl;
105 
106 }
107 
108 int main()
109 {
110     test();
111     return 0;
112 }

 


歡迎交流。


 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM