链表操作-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)

posted @ 2023-03-28 10:52  小傻孩丶儿  阅读(14)  评论(1编辑  收藏  举报