【反转子链表】模拟题

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 @ 2023-12-18 14:22  沙汀鱼  阅读(7)  评论(0编辑  收藏  举报