一、思路
請判斷一個鏈表是否爲迴文鏈表。舉例:
例1:
輸入: 1->2 輸出: false
例2:
輸入: 1->2->2->1 輸出: true
要求:時間複雜度爲O(n),空間複雜度爲O(1)(打消了借用棧的念頭)。
1.1 知識點
1.2 知識點
我們先抽象到線性表的層次來看,如何判斷線性表是否是迴文呢?使用兩個迭代器i,j;i指向開頭,j指向結尾;在i不斷自增和j不斷自減的過程中,進行比較——直到比較了一半爲止。
問題來了,單鏈表不支持後退,怎麼辦?逆向思維:如果把後半部分逆置的話,再用一根指針指向開頭,一根指針指向中間,依次進行比較就可以了。這就是剛剛提到到,通過算法單鏈表的中間結點,找到這一半;通過算法單鏈表的反轉,逆置後半部分;一根指針指向開頭,一根指針指向中間就可以進行比較了。
ListNode *middleNode(ListNode *head) //找到鏈表的中間結點
{
if (!head || !head->next) return head; //空表或只有1個結點,返回自身
ListNode *slow = head, *fast = head->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow->next;
}
ListNode *reverse(ListNode *head) {
if (!head || !head->next) return head; //空表或者只有1個結點,無需反轉
ListNode *prev = NULL, *current = head, *save;
while (current) {
save = current->next;
current->next = prev;
prev = current;
current = save;
}//遍歷完成,也即鏈表逆置完成
return prev;
}
bool isPalindrome(ListNode* head) {
if (!head || !head->next) return true; //空表或者只有1個結點,默認爲迴文
ListNode *cmp1, *cmp2;
cmp1 = head;
cmp2 = reverse(middleNode(head));
while (cmp1 && cmp2) {
if (cmp1->val != cmp2->val) return false;
cmp1 = cmp1->next; cmp2 = cmp2->next;
}
return true;
}