链表操作-leetcode 92 -反转链表2
题目描述: 给你单链表的头指针 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)
不恋尘世浮华,不写红尘纷扰