該題目的要求是判斷一個單鏈表是否是回文鏈表,題目的難度在於O(n)時間和O(1)空間的限制。
由於單鏈表不能反向訪問,所以不能直接通過原來的鏈表來判斷,解題的思路是首先對原來的鏈表的前半部分進行判斷,然後進行判斷(如鏈表為“12344321” 反轉之後為“43214321”)。想到這一點之後的實現就非常簡單了,完整的代碼如下所示:
class Solution { public: ListNode* reverseHalf(ListNode* root){ ListNode *fast = root, *slow = root; //slow 指向要反轉的部分的後一個節點 while(fast != nullptr && fast -> next != nullptr){ fast = fast -> next -> next; slow = slow -> next; } ListNode *h = new ListNode(0); h -> next = root; //執行反轉 ListNode *sec = root, *fir = root -> next; while(fir != slow){ sec -> next = fir -> next; fir -> next = h -> next; h -> next = fir; fir = sec -> next; } return h -> next; } bool isPalindrome(ListNode* head) { int len = 0; ListNode* p = head; ListNode *fast, *slow; //計算單鏈表的長度 while(p != NULL){ len++; p = p -> next; } if(len < 2) return true; //反轉單鏈表的前半部分 ListNode* reversedList = reverseHalf(head); //slow 指向單鏈表的中間位置 fast = slow = reversedList; while(fast != nullptr && fast -> next != nullptr){ fast = fast -> next -> next; slow = slow -> next; } //fast 指向單鏈表的頭部 fast = reversedList; if(len % 2 != 0) slow = slow -> next; //判斷是否為回文子串 while(slow != nullptr){ if(fast -> val != slow -> val) return false; fast = fast -> next; slow = slow -> next; } return true; } };