題目描述: 給你單鏈表的頭指針 head 和兩個整數 left 和 right ,其中 left <= right 。請你反轉從位置 left 到位置 right 的鏈表節點,返回 反轉後的鏈表 。
示例: 輸入:head = [1,2,3,4,5], left = 2, right = 4 輸出:[1,4,3,2,5]
解析: 這道題和反轉整個鏈表有些類似,只不過這次需要判斷反轉的位置範圍。先遍歷到第 left 個節點,然後開始進行鏈表的反轉,直到第 right 個節點爲止,在反轉前需要特別注意保存區間頭結點和尾結點後面的節點,以便在反轉時連接它們。
思路:
需要一個虛擬頭節點連接head,作爲存儲結果,然後設置一個pre指針,迭代到left前的那個節點,在創建curr,tail倆個節點分別反轉left,right區域內的節點,最後tail會指向right那個節點,此時left,right區域內的節點就反轉完了,此時pre。next。next指向tail,pre.next只想反轉後的頭節點curr,返回dummy.next,至此結束,代碼如下
//leetcode submit region begin(Prohibit modification and deletion)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
if (head == null || head.next == null || left == right) {
return head;
}
//記錄結果
ListNode dummy = new ListNode(-1);
dummy.next = head;
//只想要反轉那個左節點的前一個節點
ListNode pre=dummy;
for (int i = 1; i < left; i++) {
pre =pre.next;
}
//分別記錄當前和下一個節點,爲反轉做準備
ListNode curr = pre.next;
ListNode tail = curr.next;
//在這段代碼中,tail 是指向當前正在處理的節點 cur 的下一個節點。在翻轉鏈表區間時,我們需要記錄區間開始時的前驅節點和後繼節點,其中後繼節點即爲 tail。在具體實現上,我們用 cur 指向需翻轉的節點,再用 tail 記錄 cur 的後繼節點。然後依次翻轉節點,每次將 cur 的 next 指針指向它的前
for (int i = left; i <right ; i++) {
ListNode next = tail.next;
tail.next = curr;
curr = tail;
tail = next;
}
//System.out.println("curr: "+curr.val);
//System.out.println("tail: "+tail.val);
//注意操作順序,否則會導致鏈表結構問題
pre.next.next = tail;
pre.next = curr;
return dummy.next;
}
}
//leetcode submit region end(Prohibit modification and deletion)