当前位置:首页 > 力扣题解 > 链表分组反转的智慧:力扣2074题的优雅解法全解析

链表分组反转的智慧:力扣2074题的优雅解法全解析

2天前力扣题解41

截图未命名.jpg 链表分组反转的智慧:力扣2074题的优雅解法全解析 链表分组反转 偶数长度组处理 力扣2074题 链表算法优化 指针操作技巧 第1张

一、问题描述

给定一个单链表的头节点head,我们需要:

  1. 链表节点分成若干组

  2. 第i组的长度为i(即第1组1个节点,第2组2个节点,依此类推)

  3. 反转所有偶数长度组中的节点顺序

  4. 最后返回修改后的链表

示例:

输入:head = [5,2,6,3,9,1,7,3,8,4]

输出:[5,6,2,3,9,1,4,8,3,7]


二、解题思路

采用"分组处理+条件反转"策略:

  1. 遍历链表时动态确定当前组长度

  2. 记录每组起始和结束位置

  3. 对偶数长度组执行反转操作

  4. 处理边界条件(剩余节点不足时)


三、完整代码

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);
                groupStart->next = nextGroup;
                prev = groupStart;
            } else {
                // 奇数长度组不处理
                prev = groupEnd;
            }
            
            groupNum++;  // 准备处理下一组
        }
        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;
            curr = next;
        }
        return prev;
    }
};


四、算法详解

1. 数据结构准备

  • 使用虚拟头节点(dummy)简化边界处理

  • prev指针始终指向上一组的尾节点

  • groupNum记录当前应该是第几组(决定预期长度)

2. 核心处理流程

  1. 确定组边界‌:遍历找出当前组的起始(start)和结束(end)节点

  2. 长度检查‌:统计实际节点数,处理剩余节点不足的情况

  3. 条件反转‌:仅当实际长度为偶数时才执行反转

  4. 重新连接‌:将反转后的子链表重新接入主链表

3. 反转子链表

  • 标准的三指针反转法(prev, curr, next)

  • 注意要先断开子链表与原链表的连接

  • 反转后要正确设置新的连接点

五、关键点解析

1. 边界处理技巧

  • 使用dummy节点避免头节点特殊处理

  • 每次循环后prev指针的正确更新

  • 剩余节点不足时按实际长度处理

2. 反转条件控制

  • 仅当count % 2 == 0时才执行反转

  • 反转前后要正确处理链表连接

  • 奇数长度组只需移动prev指针

3. 复杂度控制

  • 每个节点只被访问常数次

  • 反转操作是原地进行的

  • 不需要额外空间

六、常见错误分析

  1. 组长度计算错误‌:忘记处理剩余节点不足的情况

  2. 反转后连接错误‌:没有正确设置groupStart->next

  3. 指针更新错误‌:prev指针没有根据是否反转来正确更新

  4. 边界条件遗漏‌:空链表或单节点链表的处理


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

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