leetcode 92 反轉連結串列Ⅱ

October-11發表於2020-10-17

這道題是我小米麵試時手撕的一道題,當時沒撕出來QAQ,太慘了,只能下定決心好好搞演算法,面試官還問我怎麼沒刷到這個題。。。。我是真沒刷到這道題,反轉單連結串列倒是熟的不行。反轉連結串列真的是高頻考點,得好好看各種變種題。

反轉從位置 m 到 n 的連結串列。請使用一趟掃描完成反轉。
說明
1 ≤ m ≤ n ≤ 連結串列長度。

示例:

輸入: 1->2->3->4->5->NULL, m = 2, n = 4
輸出: 1->4->3->2->5->NULL

解題思路:
反轉思路和反轉單連結串列得思路差不多,問題在於邊界得判斷。解題步驟如下:

  • 找到反轉部分的起點即m點,以及前面的那個節點,用兩個指標con和tail儲存。con需要連線到n節點,pre成為反轉後的頭
  • 三指標法(pre,cur,suf)反轉連結串列,直到pre==n,此時,另外cur指向n後面的節點,將反轉後的尾節點tail指向cur,反轉完畢

值得注意的一點:在尋找m的前一個節點時,迴圈的邊界條件不好確定,容易亂,比如m=2時,如果從頭節點開始遍歷,此時頭節點就是m的前一個節點,不好設定邊界。因此,引入啞節點,則尋找起來更加容易。

程式碼:

class Solution {
public:
	ListNode* reverseBetween(ListNode* head, int m, int n) {
		ListNode* Node = new ListNode(-1);
		Node -> next = head;
		ListNode* pre = Node;
		ListNode* cur;
		for (int i = 1; i < m; i++) {
			pre = pre -> next;				//尋找m的前一個節點
		}
		cur = pre -> next;					//反轉的起點,也是反轉後的尾點
		ListNode* con = pre;
		ListNode* tail = cur;				//儲存兩個節點
		ListNode* suf;
		for (int i = m; i <= n; i++) {		//反轉[m,n]之間的連結串列
			suf = cur -> next;
			cur -> next = pre;
			pre = cur;
			cur = suf;
		}
		if (con) {
			con -> next = pre;				//如果不是從頭開始反轉
		}
		tail -> next = cur;
		return Node -> next;
 	}
};

相關文章