1. 程式人生 > >判斷一個單鏈表是否是迴文連結串列

判斷一個單鏈表是否是迴文連結串列

思路有三種:

1.用棧順著連結串列儲存所有元素,然後依次出棧從頭再比較。時間複雜度O(N),空間複雜讀O(N)。

2.還是棧,不過只儲存前一半元素,然後和後一半對比即可。時間複雜度O(N),空間複雜度O(N/2)。

3.利用連結串列逆序思想,將連結串列後半部分逆序。然後從前到中和從後到中一一對比即可。這種情況要注意將中間指標next指向要賦一次空,不然會導致死迴圈。同時我們得出結果後,不論真與假,都應該還原連結串列,函式尾部返回。

程式碼如下:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        if(pHead == NULL || pHead->next == NULL)
            return true;
        
        ListNode* n1 = pHead;
        ListNode* n2 = pHead;
       
        while(n2->next != NULL && n2->next->next != NULL){
            n2 = n2->next->next;
            n1 = n1->next;
        }
        
        n2 = n1->next;
        n1->next = NULL;  //本題關鍵
        ListNode* n3 = NULL;
        while(n2 != NULL){
        	n3 = n2->next;
            n2->next = n1;
            n1 = n2;
            n2 = n3;
        }
        
        n3 = n1;   //儲存最後一個結點
        n2 = pHead;
        bool res = true;
        while(n1 != NULL && n2 != NULL){
            if(n1->val != n2->val){
                res = false;
                break;
            }
            n1 = n1->next;
            n2 = n2->next;
        }
        
        //不管是否成功都還原連結串列
        n2 = n3->next;
        n3->next = NULL;  //尾指標賦空
        while(n2 != NULL){
            n1 = n2->next;
            n2->next = n3;
            n3 = n2;
            n2 = n1;
        }
        
        return res;
    }
};