给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:


css

体验AI代码助手

代码解读

复制代码

输入: head = [1,2,3,4,5], left = 2, right = 4 输出: [1,4,3,2,5]

示例 2:


css

体验AI代码助手

代码解读

复制代码

输入: head = [5], left = 1, right = 1 输出: [5]

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

进阶:  你可以使用一趟扫描完成反转吗?

以下是反转链表指定区间的 Java 实现。代码使用虚拟头节点简化边界情况处理,并通过四步定位法完成反转操作:


ini

体验AI代码助手

代码解读

复制代码

java 复制 /** * 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) { // 创建虚拟头节点简化操作 ListNode dummy = new ListNode(-1, head); ListNode prev = dummy; // Step 1: 定位 left 前一个节点 for (int i = 0; i < left - 1; i++) { prev = prev.next; } // Step 2: 定位三个关键节点 ListNode leftNode = prev.next; ListNode curr = prev.next; ListNode next; // Step 3: 反转区间链表 ListNode newTail = leftNode; // 反转后的新尾部 ListNode preReverse = null; // 反转前驱指针 // 反转指定区间内的链表 for (int i = 0; i < right - left + 1; i++) { next = curr.next; curr.next = preReverse; preReverse = curr; curr = next; } // Step 4: 重新连接链表 prev.next = preReverse; // 连接左段 newTail.next = curr; // 连接右段 return dummy.next; } }

算法思路说明:

  1. 虚拟头节点​:创建 dummy 节点指向头节点,处理 left=1 的反转情况

  2. 四步定位​:

    • prev:指向 left 前一个节点
    • leftNode:反转区间起始节点(反转后成为新尾部)
    • preReverse:反转区间后的新头节点
    • curr:反转区间后的下一个节点
  3. 反转过程​:

    • 遍历从 left 到 right 的节点

    • 采用标准的链表反转三指针法:

      
          

      ini

      体验AI代码助手

      代码解读

      复制代码

      java 复制 next = curr.next; // 临时保存后续节点 curr.next = prev; // 反转指针方向 prev = curr; // 移动前驱指针 curr = next; // 移动当前指针
  4. 重新连接​:

    • 将反转后的链表头 (preReverse) 连接到左段 (prev.next)
    • 将反转后的链表尾 (newTail) 连接到右段 (curr)

复杂度分析:

  • 时间复杂度​:O(n)

    • 最坏情况需要完整遍历整个链表(当 left=1, right=n 时)
    • 实际操作只需完成单次遍历
  • 空间复杂度​:O(1)

    • 仅使用常量额外空间(几个指针变量)

示例验证:

示例 1​:head = [1,2,3,4,5], left=2, right=4

  1. 定位:prev=1, leftNode=2, newTail=2

  2. 反转区间:

    • 反转 [2,3,4] → [4,3,2]
    • preReverse=4, curr=5
  3. 连接:

    • 1 → 4(左段连接)
    • 2 → 5(右段连接)
    • 结果:1 → 4 → 3 → 2 → 5

示例 2​:head = [5], left=1, right=1

  1. 定位:prev=dummy, leftNode=5, newTail=5
  2. 反转区间:单个节点不变
  3. 连接:dummy → 5 → null
  4. 返回 [5]

此实现满足题目要求,能正确处理各种边界情况(包括从头反转、反转整个链表等特殊情况)。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐