單鏈表-迴文鏈表

題目來源LeetCode第234題

一、思路

請判斷一個鏈表是否爲迴文鏈表。舉例:

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章