92. 反转链表 II
力扣题目
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
代码
思路:p固定不变,不断把q后面的节点插入到p后面,用头插法
/**
* 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)
return head;
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode p = dummy;
ListNode q = dummy.next;
for (int i = 0; i < left - 1; i++){
p = p.next;
q = q.next;
}
for (int i = left; i < right; i++){
ListNode tmp = q.next;
q.next = tmp.next;
tmp.next = p.next;
p.next = tmp;
}
return dummy.next;
}
}
方法二:
思路:把链表断开成3部分,反转的部分是第二部分,反转后再拼接
/**
* 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)
return head;
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode p = dummy;
ListNode reverseHead = dummy.next;
//p表示要反转的开头节点的前一个节点
//reverseHead表示反转链表的头结点,即left那里
for (int i = 0; i < left - 1; i++){
p = p.next;
reverseHead = reverseHead.next;
}
//断开原始链表,变成三部分
p.next = null;
//reverseTail表示right后面的节点,不包括right,即第三部分的节点,第二部分是要反转的节点
ListNode reverseTail = reverseHead;
for (int i = left; i < right; i++){
reverseTail = reverseTail.next;
}
//q表示第二部分的最后一个节点,找到它并把它next指针指向null
ListNode q = reverseTail;
reverseTail = reverseTail.next;
q.next = null;
//迭代法反转链表
ListNode newHead = reverse(reverseHead);
//第一部分拼接反转后的链表
p.next = newHead;
//找到第二部分的末尾节点
while (newHead.next != null){
newHead = newHead.next;
}
//第二部分拼接第三部分节点
newHead.next = reverseTail;
return dummy.next;
}
private ListNode reverse(ListNode head){
ListNode newHead = null;
while (head != null){
//tmp用于指向断开的head节点,然后head指向head的下一个节点,
// tmp属于断开状态,然后把tmp添加到新的链表,然后newHead指向刚搬过来的tmp
//这样newHead指针就永远是新链表即反转后的链表的头指针
ListNode tmp = head;
head = head.next;
tmp.next = newHead;
newHead = tmp;
}
return newHead;
}
}