链表内指定区间反转

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

    public ListNode reverseBetween (ListNode head, int m, int n) {
        // write code here
        //处理特殊情况
        if(head==null||head.next==null||m==n){
            return head;
        }
        //创建哨兵节点方便操作
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        //前驱
        ListNode prev=dummy;
        //移动前驱prev到m-1的位置
        for(int i=1;i<m;i++){
            prev=prev.next;
        }
        //创建当前节点cur和待处理节点curNext
        ListNode cur=prev.next;
        ListNode curNext=null;
    //实现m~n区间的反转
        for(int i=m;i<n;i++){
            curNext=cur.next;
            cur.next=curNext.next;
            curNext.next=prev.next;
            prev.next=curNext;
        }
        return dummy.next;//返回头节点
    }

函数签名

public ListNode reverseBetween(ListNode head, int m, int n)

        这个函数接受一个链表的头节点 head 和两个整数 mn 作为参数,其中 m 和 n 表示需要反转的链表区间的起始和结束位置(位置从 1 开始计数)。函数返回反转后链表的头节点。

特殊情况处理

if(head==null||head.next==null||m==n){
return head;
}
  • 如果链表为空(head == null),则无需反转,直接返回 null(但这里实际上返回了 head,即 null,因为 head 已经是 null)。
  • 如果链表只有一个节点(head.next == null),则不存在需要反转的区间,直接返回 head
  • 如果 m 等于 n,表示没有需要反转的区间,也直接返回 head

创建哨兵节点

ListNode dummy=new ListNode(0);
dummy.next=head;
  • 创建一个哨兵节点(dummy node)dummy,其 next 指向链表的头节点 head。哨兵节点用于处理当 m 为 1 时(即头节点需要被反转)的特殊情况,确保 prev 节点不会变成 null

移动前驱节点

ListNode prev=dummy;
for(int i=1;i<m;i++){
prev=prev.next;
}
  • 初始化一个前驱节点 prev,并将其指向哨兵节点 dummy
  • 通过循环将 prev 移动到第 m-1 个节点的位置。注意,这里的循环是从 1 开始,直到 i 小于 m

反转区间

ListNode cur=prev.next;
ListNode curNext=null;
for(int i=m;i<n;i++){
curNext=cur.next;
cur.next=curNext.next;
curNext.next=prev.next;
prev.next=curNext;
}
  • 初始化当前节点 cur 为 prev.next,即第 m 个节点。
  • 在每次循环中,首先保存 cur 的下一个节点到 curNext
  • 然后,将 cur 的 next 指针指向 curNext 的下一个节点,即跳过 curNext
  • 接着,将 curNext 的 next 指针指向 prev.next,即将 curNext 插入到 prev 和 cur 之间。
  • 最后,更新 prev.next 为 curNext,完成一次反转操作。
  • 注意,这里的循环条件是 i < n 而不是 i <= n,因为我们只需要反转到 n-1 的节点,而 n 位置的节点应该保持不变。

返回结果

return dummy.next;
  • 由于可能存在头节点被反转的情况,我们返回哨兵节点的 next 属性,它始终指向反转后链表的真正头节点(如果头节点没有被反转,则仍然是原始的 head)。

注意事项

  • 这个函数假设输入的 m 和 n 是有效的,即它们位于链表的长度范围内。
  • 链表节点的值没有在这个函数中被修改,只有节点的连接关系被改变了。
  • 如果 m 为 1,则头节点可能会被反转,因此使用哨兵节点来确保操作的正确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值