算法 - 链表 -- 反转链表区间[m,n] 或者 反转链表前N个节点

我们前面写过一个算法是反转链表 https://www.cnblogs.com/wphl-27/p/19885408

这道题有点不一样的是,它不反转整个链表,而是反转链表中的一个区间[m,n], 还有一个算法题是反转链表前N个节点,和这个也类似

using System;

// 定义链表节点
public class ListNode
{
    public int val;
    public ListNode next;
    public ListNode(int val = 0, ListNode next = null)
    {
        this.val = val;
        this.next = next;
    }
}

public class Solution
{
    /// <summary>
    /// 反转链表中从位置 m 到 n 的节点
    /// </summary>
    /// <param name="head">链表头节点</param>
    /// <param name="left">起始位置 m (1-indexed)</param>
    /// <param name="right">结束位置 n (1-indexed)</param>
    /// <returns>反转后的链表头节点</returns>
    public ListNode ReverseBetween(ListNode head, int left, int right)
    {
        // 边界检查:如果不需要反转或链表为空
        if (head == null || left == right)
        {
            return head;
        }

        // 1. 创建虚拟头节点,简化 m=1 时的处理逻辑
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        // 2. 找到 left 的前一个节点 (pre)
        // 我们需要移动 left - 1 步
        ListNode pre = dummy;
        for (int i = 0; i < left - 1; i++)
        {
            pre = pre.next;
        }

        // 3. 开始局部反转
        // cur 指向当前要处理的节点(初始为 left 位置的节点)
        ListNode cur = pre.next;
        
        // 执行 n - left 次头插法操作
        // 每次将 cur 的下一个节点移到 pre 的后面
        for (int i = 0; i < right - left; i++)
        {
            ListNode nextNode = cur.next;      // 暂存 cur 的下一个节点
            cur.next = nextNode.next;          // cur 跳过 nextNode,指向下下个节点
            nextNode.next = pre.next;          // nextNode 插入到 pre 之后(即当前反转部分的头部)
            pre.next = nextNode;               // 更新 pre 的 next 指向新的头部
        }

        // 4. 返回结果
        // 注意:如果 left == 1,dummy.next 已经指向了新的头节点
        return dummy.next;
    }
}

 

posted on 2026-09-27 17:27  新西兰程序员  阅读(1)  评论(0)    收藏  举报