1. 程式人生 > >leetcode 刷題之路 17 Reorder List

leetcode 刷題之路 17 Reorder List

Given a singly linked list LL0L1→…→Ln-1Ln,
reorder it to: L0LnL1Ln-1L2Ln-2→…

You must do this in-place without altering the nodes' values.

For example,

Given {1,2,3,4}, reorder it to {1,4,2,3}.

按照特定規律重排連結串列:將連結串列分為長度相同或者相差1的兩部分,對後半部分進行逆序處理,然後將這兩部分每次取一個節點連線起來,構成一個新的連結串列。具體實施步驟為設定fast和slow兩個指標,fast指標每次前進兩個節點,slow每次前進一個節點,這樣當fast指標到連結串列尾的時候,slow節點剛好到連結串列中間位置,此時需要將前一部分的連結串列尾設定為NULL,以slow的下一個節點表示後半部分的開始節點,對後半部分進行逆序操作(reverseListNode函式),逆序操作完成後,進行連線操作,每次從兩個連結串列中取一個節點加入到新連結串列中直到到達某一個連結串列的結尾或者兩個連結串列的結尾,最後再將另一個連結串列剩餘部分加入到新連結串列當中,將head指標重新指向連結串列的第一個節點即可。

這道題做了挺長時間才測試通過,在沒有想好一個清晰的思路之前就動手寫程式碼,期望能夠在寫的過程中逐漸理清思路,結果測試通不過時候,又在沒想清楚條件下改動程式,抱著僥倖的心理試了好多次都有各種錯誤,搞得心情很煩躁,最後還是趁著出去透氣的時候認真理了理思路,理清思路後回來一口氣寫出來就通過了。總結一下,寫程式碼是解題的最後一步,只要腦中有了清晰的思路,嚴密的考量,寫程式碼就像把腦子裡面的東西抄寫到螢幕上一樣簡單,只能說我的火候還不夠。

程式碼:

class Solution {
public:
	void reorderList(ListNode *head)
	{
		if (head == NULL || head->next == NULL)
			return;
		ListNode *slow, *fast;
		fast = slow = head;
		ListNode* pPre=NULL;
		while (fast!= NULL && fast->next!= NULL)
		{
			fast = fast->next->next;
			slow = slow->next;
		}

		ListNode *dummyHead = new ListNode(0);
		dummyHead->next = slow->next;
		slow ->next = NULL;
		reverseListNode(dummyHead);
		
		fast = dummyHead->next;
		slow = dummyHead;
		while (head != NULL&&fast != NULL)
		{
			slow->next = head;
			head = head->next;
			slow = slow->next;
			slow->next = fast;
			fast = fast->next; 
			slow = slow->next;
		}
		if (head == NULL)
		{
			slow->next = fast;
			head = dummyHead->next;
			delete dummyHead;
			return;
		}
		if (fast == NULL)
		{
			slow->next = head;
			head = dummyHead->next;
			delete dummyHead;
			return;
		}
	}
	static void reverseListNode(ListNode *head)
	{
		if (head == NULL || head->next == NULL)
			return;
		ListNode *pCur, *pPre;
		pPre = head->next;
		pCur = pPre->next;
		while (pCur != NULL)
		{
			pPre->next = pCur->next;
			pCur->next = head->next;
			head->next = pCur;
			pCur = pPre->next;
		}
	}

};