1. 程式人生 > 其它 >力扣234、迴文連結串列

力扣234、迴文連結串列

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 };