leetcode 92. 反转链表 II

一、题目

给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

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

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

二、代码

思路:

  • 首先找到四个节点:prev,succ,leftNode,rightNode(leftNode和rightNode是要反转的头尾节点,prev是leftNode之前的节点,succ是rightNode之后的节点)
  • 将要反转的子链表先断开(prev和rightNode的next均设为nullptr)
  • 将子链表反转(方法可见 leetcode 206. 反转链表)
  • 然后将反转后的子链表和原来的连接起来
  • 为了避免left==1要分类讨论的情况,在head前面设置一个虚拟头结点,最后返回这个虚拟头结点的next即可
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    void reverseList(ListNode* head){
        ListNode* prev=nullptr,*cur=head,*next;
        while(cur){
            next=cur->next;
            cur->next=prev;
            prev=cur;
            cur=next;
        }
    }

    ListNode* reverseBetween(ListNode* head, int left, int right) {
        // 添加一个虚拟头结点,避免left=1的情况
        ListNode* vHead=new ListNode(0,head);
        ListNode* prev=vHead,*succ,*leftNode,*rightNode;

        for(int i=1;i<left;++i){
            prev=prev->next;
        }
        leftNode=prev->next;
        rightNode=prev;

        int len=right-left+1;
        for(int i=1;i<=len;++i){
            rightNode=rightNode->next;
        }
        succ=rightNode->next;
        
        // 截断链表
        prev->next=nullptr;
        rightNode->next=nullptr;
        reverseList(leftNode);

        // 重新连接
        prev->next=rightNode;
        leftNode->next=succ;
        return vHead->next;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值