牛客网高频算法题系列-BM2-链表内指定区间反转

 


牛客网高频算法题系列-BM2-链表内指定区间反转

题目描述

将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n),空间复杂度 O(1)。

原题目见:BM2 链表内指定区间反转

解法一:链表遍历,指针交换

因为起始位置可能是头结点,所以首先设置一个虚拟的头结点dummyNode并将next指向原有的头结点,然后处理过程如下:

  • 首先遍历链表,找到起始位置m的前一个结点pre,用来记录反转前的结点;
  • 然后用cur和next记录pre的next结点,用next记录cur的next结点;
  • 然后继续遍历链表,通过交换pre、next、cur的next指针,将next结点转到pre结点的下一个结点处,然后循环处理cur的下一个结点;
  • 遍历到结束结束位置n的结点即反转结束。
  • 最后,返回dummyNode结点的next结点即为反转后的链表。
public class Bm002 {
    /**
     * @param head ListNode类
     * @param m    起始位置
     * @param n    结束位置
     * @return ListNode类
     */
    public static ListNode reverseBetween(ListNode head, int m, int n) {
        if (head == null || head.next == null) {
            return head;
        }
        if (m == n) {
            return head;
        }
        // 设置虚拟头结点
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = head;
        // pre为反转区间的前一个结点
        ListNode pre = dummyNode;
        for (int i = 0; i < m - 1; i++) {
            pre = pre.next;
        }
        // cur初始为反转区间的起始结点
        ListNode cur = pre.next;
        ListNode next;
        for (int i = 0; i < n - m; i++) {
            // 通过交换next指针指向,将next结点转到pre结点的下一个结点处
            next = cur.next;
            cur.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }

        // 最后,返回dummyNode结点的next结点即为反转后的链表
        return dummyNode.next;
    }

    public static void main(String[] args) {
        ListNode head = ListNode.testCase2();
        System.out.println("指定区间反转之前");
        ListNode.print(head);

        ListNode newHead = reverseBetween(head, 2, 4);
        System.out.println("指定区间反转之后");
        ListNode.print(newHead);
    }
}

1.0136537.7834343329
0.993650.02551796445
相信坚持的力量!

posted @   醉舞经阁  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示