算法刷题之路之链表初探(7)
今天来学习的算法题是leecode92反转链表Ⅱ,是一道中等难度的入门题,话不多说!直接上!
条件
项目解释
由题目可以知道,我们需要将给定区间内的链表反转,大概上的中心思想其实和LeeCode206反转大差不差,唯一需要注意的是添加虚节点和切断原有链表和链表拼接的思想
详细可以参考
反转链表
代码
class Solution92 {
public ListNode reverseBetween(ListNode head, int left, int right) {
// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
// 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
// 建议写在 for 循环里,语义清晰
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
}
// 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
ListNode rightNode = pre;
for (int i = 0; i < right - left + 1; i++) {
rightNode = rightNode.next;
}
// 第 3 步:切断出一个子链表(截取链表)
ListNode leftNode = pre.next;
ListNode curr = rightNode.next;
// 注意:切断链接
pre.next = null;
rightNode.next = null;
reverseLinkedList(leftNode);
// 将新链表的尾连旧链表的头
pre.next = rightNode;
//将新的链表的头连旧的尾
leftNode.next = curr;
return dummyNode.next;
}
private void reverseLinkedList(ListNode head) {
// 也可以使用递归反转一个链表
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
}
}