【反转子链表】模拟题

leetcode 92. 反转链表 II

题意:反转链表的[left, right],返回链表表头

题解:直接模拟删除的过程即可

  1. 定义重要节点
    记录left位置的节点为lnode,right位置的节点为rnode
    lnode的前驱节点为pre,right位置的后继节点为suc
    初始化pre = suc = lnode = rnode = 原链表表头前的虚拟节点

  2. 使节点从虚拟节点走到定义的位置
    pre跳l-1次走到自己的位置
    lnode再从pre跳1次走到自己的位置
    rnode从lnode跳r-l次走到自己的位置
    suc从rnode跳1次走到自己的位置

  3. 反转[left, right]处的链表

  4. 修改pre和lnode的next节点
    pre.next = reverse(lnode);
    lnode.next = suc;

模拟代码
/**
* 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 {
ListNode pre, suc, lnode, rnode;
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0, head);
pre = suc = lnode = rnode = dummy;
int t = left - 1;
while(t -- > 0) {
pre = pre.next;
}
lnode = pre.next;
rnode = lnode;
t = right - left;
while(t -- > 0) {
rnode = rnode.next;
}
suc = rnode.next;
pre.next = reverse(lnode);
lnode.next = suc;
return dummy.next;
}
public ListNode reverse(ListNode head) {
if(head == rnode) return head;
ListNode res = reverse(head.next);
head.next.next = head;
head.next = null;
return res;
}
}

题解2:在需要反转的区间里,每遍历到一个节点,让这个新节点来到反转部分的起始位置。将需要反转的子链表依次移动到pre节点的后面

  1. 定义重要节点
    pre:子链表[left, right]的前驱节点
    lnode:子链表[left, right]的表头节点
    suc:lnode节点的后继节点【永远指向lnode的下一个节点】

  2. 更改第1步中三个节点的指向
    (1)lnode.next = suc.next
    (2)suc.next = pre.next
    (3)pre.next = suc

  3. 更新suc节点
    suc = lnode.next

  4. 边界条件
    lnode跳r-l次 [或者] lnode.next==null


题解2代码
/**
* 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 pre, lnode, suc;
ListNode dummy = new ListNode(0, head);
pre = lnode = suc = dummy;
int t = left - 1;
while(t -- > 0) {
pre = pre.next;
}
lnode = pre.next;
suc = lnode.next;
t = right - left;
while(t -- > 0) {
if(lnode.next == null) {
break;
} else {
lnode.next = suc.next;
suc.next = pre.next;
pre.next = suc;
suc = lnode.next;
}
}
return dummy.next;
}
}
posted @   沙汀鱼  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示