当前位置:首页 > 力扣 > LeetCode 2074题解:反转链表中的节点间隔(虚拟节点+分组反转)

LeetCode 2074题解:反转链表中的节点间隔(虚拟节点+分组反转)

7小时前

LeetCode 2074题解:反转链表中的节点间隔(虚拟节点+分组反转) 链表反转 力扣题解 链表 虚拟头节点 第1张

一、题目解读

LeetCode 2074题要求对链表进行分组反转:将链表按节点数分组,若当前组长度为偶数则反转该组节点,奇数长度则保持不变。例如,输入链表 [1,2,3,4,5,6],分组后 [1,2,3,4] 反转,[5,6] 保持原序,最终输出 [4,3,2,1,5,6]。题目难点在于如何动态划分组并处理边界条件。

二、解题思路

采用“虚拟头节点+分组计数”策略:

1. 创建虚拟头节点哑元(dummy)指向原链表头,便于处理首组反转时的边界。

2. 维护变量 prev(前组尾节点)、groupNum(当前组号,即目标长度),通过循环遍历分组。

3. 每组内用 groupStart 和 groupEnd 标记起始与末尾,计数 count 实际长度。

4. 若 count 为偶数,则切断当前组末尾连接,调用反转函数 reverseList,重新拼接至原结构;奇数组则直接跳过。

5. 循环结束后返回哑元下一节点(即真实头节点)。

三、解题步骤

1. 初始化:创建哑元节点,prev 指向哑元,groupNum 从1开始(首组目标长度为1)。

2. 循环遍历:

○ 定位当前组起始 groupStart(prev->next)。

○ 通过 groupEnd 移动并计数,直至达到目标长度或链表末尾。

○ 记录下一组起始 nextGroup(groupEnd->next)。

3. 判断组长度:

○ 偶数长度:反转子链表,调整连接(prev->next 指向反转后头,groupStart->next 指向 nextGroup),更新 prev 为 groupStart。

○ 奇数长度:直接更新 prev 为 groupEnd,跳过处理。

4. 递增 groupNum 进入下一轮,重复步骤2-3直至链表结束。

5. 返回哑元下一节点(即反转后的头节点)。

四、代码及注释

class Solution {
public:
    ListNode* reverseEvenLengthGroups(ListNode* head) {
        ListNode dummy(0, head);  // 虚拟头节点,简化边界处理
        ListNode* prev = &dummy;   // 前一组尾节点
        int groupNum = 1;          // 当前组号(决定组长度)
        
        while (prev->next) {       // 循环至链表末尾
            ListNode* groupStart = prev->next;  // 当前组起始
            ListNode* groupEnd = groupStart;    // 当前组末尾(初始与起始相同)
            int count = 1;                    // 当前组实际长度计数
            
            // 确定当前组实际长度
            while (count < groupNum && groupEnd->next) {
                groupEnd = groupEnd->next;
                count++;
            }
            
            ListNode* nextGroup = groupEnd->next;  // 下一组起始节点
            if (count % 2 == 0) {                 // 偶数长度组反转
                groupEnd->next = nullptr;         // 切断末尾连接(避免反转时影响后续组)
                prev->next = reverseList(groupStart);  // 反转并连接至 prev
                groupStart->next = nextGroup;      // 连接反转后的末尾至下一组
                prev = groupStart;                 // 更新 prev 为当前组头(反转后尾节点)
            } else {                              // 奇数长度组不处理
                prev = groupEnd;                  // 更新 prev 为当前组尾
            }
            
            groupNum++;                           // 准备处理下一组(长度+1)
        }
        return dummy.next;                       // 返回真实头节点
    }
    
private:
    ListNode* reverseList(ListNode* head) {         // 辅助函数:反转子链表
        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr) {
            ListNode* next = curr->next;         // 暂存后继节点
            curr->next = prev;                   // 反转指针
            prev = curr;                         // 更新 prev
            curr = next;                         // 移动至下一节点
        }
        return prev;                             // 返回反转后头节点
    }
};

五、总结

本解法核心在于“分组计数+按需反转”的双层逻辑,通过虚拟节点避免头节点反转的边界判断。时间复杂度为 O(n),空间复杂度为 O(1)(辅助反转函数递归空间可忽略)。关键点包括:

1. 利用 groupNum 动态控制分组长度,奇数组跳过,偶数组处理;

2. 反转时切断末尾连接,防止影响后续组;

3. 反转子链表的递归写法可替换为迭代优化。

算法兼顾效率与代码简洁性,是解决分组反转问题的典型思路。


原创内容 转载请注明出处

分享给朋友:

相关文章

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

一、题目解读力扣2846题要求解决一个基于图连通性的操作优化问题。给定一个无向图,包含边权重,以及一系列查询,每个查询询问两点间路径的最小操作次数。题目关键在于高效计算路径上权重分布的统计信息,并转化...

【牛客157题】:反转链表指定区间(虚拟头节点解法)

【牛客157题】:反转链表指定区间(虚拟头节点解法)

一、题目解读牛客第157题要求反转链表中第m到n个节点(包含m和n)的区间,并保持其他节点顺序不变。例如,给定链表1→2→3→4→5,m=2,n=4,应返回1→4→3→2→5。题目重点在于处理边界条件...

LeetCode 2778题解:平方和的高效计算与因数遍历优化(C++实现)

LeetCode 2778题解:平方和的高效计算与因数遍历优化(C++实现)

一、题目解读LeetCode 2778题要求计算数组中下标为n的因数的元素的平方和。例如,若n=6,其因数为1、2、3、6,则需计算nums[0]、nums[1]、nums[2]、nums[5]的平方...

LeetCode 2523题解:寻找区间内最小间隔质数对(C++代码)

LeetCode 2523题解:寻找区间内最小间隔质数对(C++代码)

一、题目解读LeetCode 2523题要求在一个给定的整数区间 [left, right] 内,找到间隔最小的两个质数(即相邻质数的差值最小),并返回这对质数。若区间内不存在两个质数,则返回 [-1...

力扣LCR074题区间合并算法解析:贪心排序与区间重叠处理

力扣LCR074题区间合并算法解析:贪心排序与区间重叠处理

一、题目解读力扣LCR074题要求对给定的二维区间数组(每个区间由起始点和终止点构成)进行合并,将重叠的区间合并为更宽的区间,最终输出不重叠的合并结果。例如,输入[[1,3],[2,6],[8,10]...

力扣2588题解:利用前缀异或和与哈希表求解美丽子数组问题

力扣2588题解:利用前缀异或和与哈希表求解美丽子数组问题

一、题目解读力扣2588题要求计算给定数组中“美丽子数组”的数量。所谓“美丽子数组”,是指子数组的异或和为0。题目关键在于理解子数组异或和的性质,并通过高效算法统计符合条件的子数组数量。二、解题思路采...

发表评论

访客

看不清,换一张

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