当前位置:首页 > 力扣 > 力扣第92题:三步定位 精准反转链表指定区间

力扣第92题:三步定位 精准反转链表指定区间

4个月前 (05-19)

力扣第92题:三步定位 精准反转链表指定区间 力扣 C++ 栈 链表 数据结构 算法 第1张题目解读

给定一个单链表和两个整数left与right,要求将链表中从第left个节点到第right个节点的部分进行反转,而保持其他部分不变。例如,对于链表1→2→3→4→5,left=2,right=4,反转后应为1→4→3→2→5。这个问题考察了对链表操作的熟练程度,特别是如何在不破坏链表整体结构的情况下,精确地对指定区间进行反转。


思路与过程

1.用栈结构辅助完成链表部分反转的操作。首先处理特殊情况,当left等于right时直接返回原链表。然后通过遍历链表定位四个关键节点:leftnode(反转区间起始节点)、leftlast(反转区间前一个节点)、rightnode(反转区间结束节点)和rightnext(反转区间后一个节点)。

2.找到这些关键节点后,将需要反转的区间节点依次压入中。然后根据left是否为1(即是否从链表头开始反转)分别处理:如果从头部开始反转,则更新链表头;否则将leftlast的next指向栈顶节点。最后依次弹出栈中节点完成反转,并将反转后的最后一个节点与rightnext连接起来。


代码与注释

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        if(left==right) // 特殊情况处理:不需要反转
        {
            return head;
        }
        // 定义四个关键节点指针
        ListNode* leftnode;  // 反转区间起始节点
        ListNode* leftlast;  // 反转区间前一个节点
        ListNode* rightnode; // 反转区间结束节点
        ListNode* rightnext; // 反转区间后一个节点
        ListNode* tmp=head;  // 临时指针用于遍历
        
        // 遍历链表定位关键节点
        for(int i=1;i<=right+1;i++)
        {
            if(i==left)
            {
                leftnode=tmp; // 记录反转起始节点
            }
            if(i==left-1)
            {
                leftlast=tmp; // 记录反转前一个节点
            }
            if(i==right)
            {
                rightnode=tmp; // 记录反转结束节点
            }
            if(i==right+1)
            {
                if(tmp!=rightnode)
                {rightnext=tmp;} // 记录反转后一个节点
                else
                {rightnext=nullptr;} // 处理反转到链表末尾的情况
            }
            if(tmp->next!=nullptr)
                tmp=tmp->next; // 移动指针
        }
        
        // 使用栈存储需要反转的节点
        stack<ListNode*> stk;
        while(leftnode!=rightnode->next)
        {
            stk.push(leftnode); // 压入反转区间节点
            leftnode=leftnode->next;
        }

        // 处理反转后的连接
        if(left==1) // 从链表头开始反转的情况
        {
            tmp=stk.top();
            stk.pop();
            head=tmp; // 更新链表头
        }
        else // 中间部分反转的情况
        {
            tmp=leftlast;
            tmp->next=stk.top(); // 连接反转区间前节点与反转后的第一个节点
            tmp=tmp->next;
            stk.pop();
        }

        // 完成剩余节点的反转连接
        while(!stk.empty())
        {
            tmp->next=stk.top(); // 连接反转后的节点
            tmp=tmp->next;
            stk.pop();
        }
        
        // 处理反转区间后的连接
        if(rightnext!=nullptr)
        {
            tmp->next=rightnext; // 连接反转后的最后一个节点与后续节点
        }
        else{
            tmp->next=nullptr; // 处理反转到链表末尾的情况
        }

        return head;
    }
};


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣451:ASCII数组计数法 用128个桶解决频率排序问题

力扣451:ASCII数组计数法 用128个桶解决频率排序问题

题目重解给定一个字符串,将字符按照出现频率降序排列。例如输入"tree",可能返回"eetr"或"eert"。题目要求我们不考虑字母顺序,只...

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

题目重解想象你是一名药师,有t分钟在山上采集m种草药。每种草药需要time分钟采集,价值为num。这就像考试时分配时间做题,要选择收益最大的题目组合。题目要求计算在规定时间内能获得的最大草药价值。解题...

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

一、题目解读洛谷B3617题要求将输入的八进制字符串转换为十六进制表示。题目需处理大数场景,且对输入合法性有明确限制(长度不超过1000,仅包含0-7字符)。由于八进制与十六进制无法直接转换,需借助十...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

牛客NC67题解:汉诺塔递归算法与解题步骤

牛客NC67题解:汉诺塔递归算法与解题步骤

一、题目解读牛客NC67题要求解决汉诺塔问题,这是一个经典的递归算法题目。题目给定整数n,代表汉诺塔中的盘子数量,需要输出将n个盘子从起始柱移动到目标柱的所有步骤。汉诺塔问题规则为:每次只能移动一个盘...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。