文章目錄
- 題目
- 解法一
- 跟著我一步步來
- 第一步: new 一個傀儡頭節點 newHead,且 newHead.next == head,(這樣做,我們就獲得了 head 的 前驅節點,防止頭節點head也是反轉物件,)
- 第二步:在創建一個 節點參考 prev,用來記錄 left的前驅節點(通過for回圈,讓prev指向 left的前驅節點)
- 第三步:尋找 right 位置的節點
- 第四步:記錄 rightNode 的 下一個節點的位置(rightNode.next),并將 prev.next(left位置的節點),rightNode 進行傳參 給 反轉方法myRreverse,
- 第五步: 敲寫 myReverse 方法,(跟這題 [LeetCode - 25. K 個一組翻轉鏈表](https://blog.csdn.net/DarkAndGrey/article/details/122068701?spm=1001.2014.3001.5501) 一模一樣)
- 第六步: 將 left 和 right 置回 初始位子(left <= right ),并接回鏈表,最侄訓傳逆序完成之后的原鏈表,
- 附上程式
- 解法二:
- 代碼
題目

可以參考 這題LeetCode - 25. K 個一組翻轉鏈表,因為我們第一種解放就與這題相同,
?
解法一
找到 鏈表 left ~ right 這個范圍,將它“截取出來”,單獨進行反轉,反轉完后,將之接回鏈表中,為了能夠將其接回鏈表中,我們需要獲取 left 的前驅節點,和 right 的后驅節點,(LeetCode - 25. K 個一組翻轉鏈表)
?
跟著我一步步來
第一步: new 一個傀儡頭節點 newHead,且 newHead.next == head,(這樣做,我們就獲得了 head 的 前驅節點,防止頭節點head也是反轉物件,)

?
第二步:在創建一個 節點參考 prev,用來記錄 left的前驅節點(通過for回圈,讓prev指向 left的前驅節點)

?
第三步:尋找 right 位置的節點

?
第四步:記錄 rightNode 的 下一個節點的位置(rightNode.next),并將 prev.next(left位置的節點),rightNode 進行傳參 給 反轉方法myRreverse,

?
第五步: 敲寫 myReverse 方法,(跟這題 LeetCode - 25. K 個一組翻轉鏈表 一模一樣)

?
第六步: 將 left 和 right 置回 初始位子(left <= right ),并接回鏈表,最侄訓傳逆序完成之后的原鏈表,

&ensp;
附上程式
/**
* 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 || right == left){
return head;// 頭節點為null,鏈表為空,反轉鏈表沒有意義(沒有節點給你反轉)
// right == left ,反轉一個節點,等于沒反轉,也沒有反轉的意義
// 直接回傳 head
}
ListNode newHead = new ListNode(0,head);
ListNode prev = newHead;
for(int i = 0; i < left - 1; i++){
prev = prev.next;
if(prev == null){// 防止空指標例外,另外防止 left 位置不合法(鏈表節點沒有那么多)
return head;
}
}
ListNode rightNode = prev.next;
for(int i = 0;i < right - left;i++){
rightNode = rightNode.next;
if(rightNode == null){//防止空指標例外,另外防止 right 位置不合法(鏈表節點沒有那么多)
return head;
}
}
ListNode rightNodeNext = rightNode.next;
ListNode[] reverse = myReverse(prev.next,rightNode);
prev.next = reverse[0];
rightNode = reverse[1];
rightNode.next = rightNodeNext;
return newHead.next;
}
public static ListNode[] myReverse(ListNode left,ListNode right){
ListNode prev = right.next;
ListNode p = left;
while( prev != right){
ListNode pNext = p.next;
p.next = prev;
prev = p;
p = pNext;
}
return new ListNode[]{right,left};
}
}

?
解法二:
前面 跟解法一差不多(求 left位置的節點),
代碼
/**
* 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 || right == left){
return head;// 頭節點為null,鏈表為空,反轉鏈表沒有意義(沒有節點給你反轉)
// right == left ,反轉一個節點,等于沒反轉,也沒有反轉的意義
// 直接回傳 head
}
ListNode newHead = new ListNode(0,head);
ListNode prev = newHead;
for(int i = 0; i < left - 1; i++){
prev = prev.next;
if(prev == null){// 防止空指標例外,另外防止 left 位置不合法(鏈表節點沒有那么多)
return head;
}
}
ListNode cur = prev.next;
ListNode next = null;
for(int i = 0;i < right -left;i++){
next = cur.next;
cur.next = next.next;
next.next = prev.next;
prev.next = next;
}
return newHead.next;
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/393126.html
標籤:java
上一篇:五大經典演算法思想之分治策略


