力扣234、迴文連結串列
阿新 • • 發佈:2021-11-28
1、轉成陣列處理(208ms,33%;125MB,14%)
時間複雜度O(n):複製處是O(n),判斷處是O(n/2)即O(n),相加即為O(n)
空間複雜度O(n):複製處用了大小為n的陣列存連結串列資料,即O(n)
1 bool isPalindrome(ListNode* head) { 2 //直接對連結串列處理不方便,將其轉化為動態陣列處理 3 vector<int>vec; 4 while(head!=NULL){ 5 //push_back()在陣列的最後新增一個數據 6 vec.push_back(head->val);7 head=head->next; 8 } 9 //從頭尾往中間包圍 10 for(int i=0,j=vec.size()-1;i<=j;i++,j--){ 11 if(vec[i]!=vec[j]) 12 return false; 13 } 14 return true; 15 }
2、遞迴(204ms,40%;120MB,38%):看懂了寫不出
時間複雜度O(n):用於比較了
空間複雜度O(n):迴文檢查前建立了n個堆疊幀
class Solution { ListNode* frontPointer; public: //這個函式的特點是第二個if()錯一次就全都會錯 bool recursivelyCheck(ListNode* head) { if (head != nullptr) { //先用這個if()到達連結串列最後一個數據 if (!recursivelyCheck(head->next)) { return false; } //head從最後一個數據依次往前面返回,一旦不符合條件則會產生連鎖反應if (head->val != frontPointer->val) { return false; } //如果第二個if()處的兩者相同時把前指標frontPointer往後移 //如果兩者不相同則後面再也不會執行這一語句了 frontPointer = frontPointer->next; } //作用1是當第一次到達尾部時返回真值以便不通過第一個if()去執行第二個if() //作用2是當後面程式中第二個if()的兩個值相同時再次執行作用1的類似功能 return true; } bool isPalindrome(ListNode* head) { frontPointer = head; return recursivelyCheck(head); } };
3、快慢指標+連結串列反轉(192ms,59%;115MB,62%)
時間複雜度O(n):快慢指標處、連結串列反轉處、判斷處都為O(n),綜合也為O(n)
空間複雜度O(1):因為反轉只是對原連結串列處理,堆疊幀不超過O(1)
1 class Solution { 2 public: 3 bool isPalindrome(ListNode* head) { 4 //先用first指向連結串列中間 5 ListNode* first=FastAndSlow(head); 6 //再用second儲存後半部分連結串列反轉後的首地址 7 ListNode* second1=InversList(first->next); 8 ListNode* second2=second1; 9 //用begin指向整個連結串列的首地址 10 ListNode* begin=head; 11 bool flag=true; 12 while(flag&&second1!=NULL){ 13 if(begin->val!=second1->val){ 14 flag=false; 15 } 16 begin=begin->next; 17 second1=second1->next; 18 } 19 //將後半部分連結串列重新反轉為原來的樣子 20 first->next=InversList(second2); 21 return flag; 22 } 23 24 //快慢指標,該函式作用是定位到連結串列的中間 25 ListNode* FastAndSlow(ListNode* head){ 26 ListNode* fast=head; 27 ListNode* slow=head; 28 while(fast->next!=NULL&&fast->next->next!=NULL){ 29 //快指標每次走兩格,慢指標每次走一個,結束則慢指標走一半 30 fast=fast->next->next; 31 slow=slow->next; 32 } 33 return slow; 34 } 35 36 //連結串列反轉,使用三個指標即可辦到 37 ListNode* InversList(ListNode* head){ 38 //front指向前一個數據,rear指向後一個數據,temp用於過渡 39 ListNode* front=head; 40 ListNode* rear=NULL; 41 ListNode* temp; 42 while(front!=NULL){ 43 temp=rear; 44 rear=front; 45 front=front->next; 46 rear->next=temp; 47 } 48 return rear; 49 } 50 };