题目描述:给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例 1:
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]示例 2:
输入:head = [5], left = 1, right = 1
输出:[5]
方法一:头插法
在需要反转的区间里,每遍历到一个节点,让这个新节点来到反转部分的起始位置。
第 1 步完成以后「拉直」的效果如下:
第 2 步,同理。同样需要注意 「穿针引线」操作的先后顺序。
第 2 步完成以后「拉直」的效果如下:
第 3 步,同理。
第 3 步完成以后「拉直」的效果如下:
1 | /** |
复杂度分析:
时间复杂度:O(N),其中 N 是链表总节点数。最多只遍历了链表一次,就完成了反转。
空间复杂度:O(1)。只使用到常数个变量。
执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:36.2 MB, 在所有 Java 提交中击败了12.34%的用户
方法二:递归
先定位到要开始反转的节点, 其中head往后移, m和n就要变小
当 m 等于 1 时,此时 head 就是要反转的第一个节点,调用反转链表前 n个节点的函数进行反转
- 解决思路和反转整个链表差不多,具体的区别:
- base case 变为
n == 1
,反转一个元素,就是它本身,同时要记录后驱节点。 - 反转链表中我们把
head.next
设置为 null,因为整个链表反转后原来的head
变成了整个链表的最后一个节点。但现在head
节点在递归反转之后不一定是最后一个节点了,所以要记录后驱successor
(第 n + 1 个节点),反转之后将head
连接上。
- base case 变为
1 | class Solution { |
复杂度分析
时间复杂度:O(n)
空间复杂度:O(n)
执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:36 MB, 在所有 Java 提交中击败了62.16%的用户