題目描述:
對於一個鏈表,請設計一個時間復雜度為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 }
歡迎交流。