1. 程式人生 > >鏈表回文判斷(C++)

鏈表回文判斷(C++)

spa 占用 urn 空間 val 返回 ont test iostream


題目描述:

對於一個鏈表,請設計一個時間復雜度為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 while(pSlow != NULL) 55 { 56 ListNode* tmp = pSlow->next;//保存後面的結點 57 pSlow->next=prev; 58 prev = pSlow; 59 pSlow = tmp; 60 } 61 62 ListNode* pForward = A;//指向頭結點 63 ListNode* pBackward= prev;//指向鏈表最後一個結點 64 65 while(!(pForward == pBackward || pForward->next == pBackward)) 66 { 67 if(pForward->val != pBackward->val) 68 return false; 69 pForward = pForward->next; 70 pBackward = pBackward->next; 71 } 72 return true; 73 } 74 }; 75 76 void test() 77 { 78 //創建結點 79 ListNode* pNode1 = create_list_node(1); 80 ListNode* pNode2 = create_list_node(7); 81 ListNode* pNode3 = create_list_node(2); 82 ListNode* pNode4 = create_list_node(2); 83 ListNode* pNode5 = create_list_node(7); 84 ListNode* pNode6 = create_list_node(1); 85 // ListNode* pNode7 = create_list_node(13); 86 // ListNode* pNode8 = create_list_node(45); 87 // ListNode* pNode9 = create_list_node(-7); 88 89 //連接結點 90 connect_list_node(pNode1,pNode2); 91 connect_list_node(pNode2,pNode3); 92 connect_list_node(pNode3,pNode4); 93 connect_list_node(pNode4,pNode5); 94 connect_list_node(pNode5,pNode6); 95 // connect_list_node(pNode6,pNode7); 96 // connect_list_node(pNode7,pNode8); 97 // connect_list_node(pNode8,pNode9); 98 99 PalindromeList test; 100 101 bool flag=test.chkPalindrome(pNode1); 102 cout<<flag<<endl; 103 104 } 105 106 int main() 107 { 108 test(); 109 return 0; 110 }

歡迎交流。


鏈表回文判斷(C++)