https://leetcode-cn.com/problems/reverse-linked-list-ii/submissions/
對於指定區間的鏈表反轉和完全的鏈表反轉,其區別點在於
- 首先定位到反轉區間,只針對反轉區間進行反轉操作
- 將原始鏈表中不需要反轉的區間和最終反轉成功的反轉鏈表進行連接合並(核心點就在於需要記錄三個區間的位置)
對於具體的反轉鏈表依然是使用雙指針來實現具體的反轉操作
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { if(head == null){ return head; } // 前置節點 ListNode prev = null; // 當前節點 ListNode current = head; // 1: 首先采用雙指針定位到 反轉鏈表開始位置 while(m > 1){ // 對於m 而言 "1" 代表第一個元素 prev = current; current = current.next; m--; n--; } // 2: 定義 鏈表反轉后,對於反轉列表區間 中 head節點的前置節點以及反轉鏈表的尾節點 ListNode reverseHeadPrev = prev; ListNode reverseTail = current; // 3: 使用 prev 和 current節點開始往后遍歷,執行反轉操作 while(n > 0){ // 記錄臨時變量維護斷開連接后的后續節點位置 ListNode temp = current.next; // 進行鏈表反轉操作,將當前 current節點的next指針指向 其前置節點 prev current.next = prev; // 將prev 和 current節點向后移動一位 prev = current; current = temp; n--; } // 4: 當鏈表反轉操作結束后prev指向 反轉后鏈表的頭節點, current指向原始鏈表 反轉區間最大區間的位置+1 // 相當於此時最多存在三個分離的鏈表 // head鏈表 其尾節點為 reverseHeadPrev 指針執行位置 // 反轉鏈表 頭節點為 prev 指針指向位置 // (n,鏈表最大長度] 區間位置的鏈表 ,其頭節點為 current指針指向位置 // 將三個鏈表進行連接到一起 if(reverseHeadPrev == null){ // 說明反轉鏈表的開始區間從第一個節點位置開始,因此最后反轉鏈表的頭節點就作為整個鏈表的頭節點 head = prev; }else{ // 說明當前反轉鏈表開始區間並非從第一個節點位置開始,因此在從第一個節點位置到開始反轉位置[0,m)作為反轉鏈表的前驅節點(鏈表) reverseHeadPrev.next = prev; } // 連接尾節點, 使用反轉鏈表的尾節點 reverseTail 連接 最后的鏈表 current reverseTail.next = current; return head; } }