反转链表II

LeetCode地址

题目

  给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回反转后的链表 ,如下图所示:
  使用一次遍历完成反转。
在这里插入图片描述

输入:head = [1,2,3,4,5], left = 2, right = 4 输出:[1,4,3,2,5]

  又如,下述示例:

输入:head = [5], left = 1, right = 1 输出:[5]

双指针法

  所谓双指针法就是,一个指针用指向第一个需要反转节点的前一个节点,一个指针指向第一个要反转的节点上。

算法思路

  1. 定义一个指针pre指向第一个需要翻转节点的前一个节点和一个指针point指向第一个要反转的节点。如[1,2,3,4,5],left=2,right=4,pre指针就会指向值为1的节点上,point指针就会指向值为2的节点上。
  2. 当根据left将指针pre和指针point移动到指定位置后,开始正式的反转运算。
  3. 暂存point后一个节点定义为node。
  4. 将point的下一个节点指向point的下一个节点的下一个节点。
  5. 将node的下一个节点指向pre的下一个节点,即头插法。
  6. 将pre的下一个节点指向node。
  7. 重复步骤3-6完成left至right之间节点的反转。

算法步骤

在这里插入图片描述

  1. 经过一轮循环将指针pre和指针point移动到left-1下标的节点和left下标的节点,此时pre=1,point=2;
  2. 循环left至right下标的节点,开始反转运算;
  3. 反转运算第一步,暂存point的下一个节点定义为node;
  4. 反转运算第二步,将point的下一个节点指向point的下一个节点的下一个节点;
  5. 反转运算第三步,将暂存节点node的下一个节点指向pre的下一个节点;
  6. 反转运算第四部,将pre的下一个节点指向暂存节点node,至此完成第一轮反转运算;
  7. 重复步骤2-6直到完成所有节点的反转。

编码

/**
 * 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) {
        if(head == null || left == right || left > right){
            return head;
        }
        
        ListNode res = new ListNode(-1);
        res.next = head;
        
        ListNode pre = res;
        ListNode point = res.next;
        
        for(int i=1; i<=left-1; i++){
            pre = pre.next;
            point = point.next;
        }
        
        for(int j=1; j<=right-left; j++){
            // 反转left-right间节点
            ListNode node = point.next;
            point.next = point.next.next;
            
            node.next = pre.next;
            pre.next = node;
        }
        return res.next;
    }
}

复杂度分析

  根据以上算法思路和编码实现,时间复杂度为O(n),空间复杂度为O(1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐只乐之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值