牛客網高頻演算法題系列-BM2-連結串列內指定區間反轉
題目描述
將一個節點數為 size 連結串列 m 位置到 n 位置之間的區間反轉,要求時間複雜度 O(n),空間複雜度 O(1)。
原題目見:BM2 連結串列內指定區間反轉
解法一:連結串列遍歷,指標交換
因為起始位置可能是頭結點,所以首先設定一個虛擬的頭結點dummyNode並將next指向原有的頭結點,然後處理過程如下:
- 首先遍歷連結串列,找到起始位置m的前一個結點pre,用來記錄反轉前的結點;
- 然後用cur和next記錄pre的next結點,用next記錄cur的next結點;
- 然後繼續遍歷連結串列,通過交換pre、next、cur的next指標,將next結點轉到pre結點的下一個結點處,然後迴圈處理cur的下一個結點;
- 遍歷到結束結束位置n的結點即反轉結束。
- 最後,返回dummyNode結點的next結點即為反轉後的連結串列。
public class Bm002 {
/**
* @param head ListNode類
* @param m 起始位置
* @param n 結束位置
* @return ListNode類
*/
public static ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null || head.next == null) {
return head;
}
if (m == n) {
return head;
}
// 設定虛擬頭結點
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
// pre為反轉區間的前一個結點
ListNode pre = dummyNode;
for (int i = 0; i < m - 1; i++) {
pre = pre.next;
}
// cur初始為反轉區間的起始結點
ListNode cur = pre.next;
ListNode next;
for (int i = 0; i < n - m; i++) {
// 通過交換next指標指向,將next結點轉到pre結點的下一個結點處
next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
// 最後,返回dummyNode結點的next結點即為反轉後的連結串列
return dummyNode.next;
}
public static void main(String[] args) {
ListNode head = ListNode.testCase2();
System.out.println("指定區間反轉之前");
ListNode.print(head);
ListNode newHead = reverseBetween(head, 2, 4);
System.out.println("指定區間反轉之後");
ListNode.print(newHead);
}
}
$1.01^{365} ≈ 37.7834343329$
$0.99^{365} ≈ 0.02551796445$
相信堅持的力量!