12.6 - K个一组翻转链表 && C 编译到执行的4个阶段
目录
1.K个一组翻转链表
25. K 个一组翻转链表 - 力扣(LeetCode)
https://leetcode.cn/problems/reverse-nodes-in-k-group/description/
/**
* 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:
ListNode* reverseKGroup(ListNode* head, int k) {
// 创建哨兵节点简化头节点处理
ListNode* dummy = new ListNode(0);
dummy->next = head;
// 创建pre和end指针
// 分别标记当前组起始位置的前驱节点和组尾节点
ListNode* pre = dummy;
ListNode* end = dummy;
while(end->next != nullptr)
{
// 1. 移动end到组尾节点 && 检查剩余节点个数是否满足k个
for(int i = 0; i < k; i++)
{
end = end->next;
// 如果不足k个节点,直接返回结果
if(end == nullptr)
return dummy->next;
}
// 记录下一组的起始节点
ListNode *nextGroup = end->next;
// 当前组的起始节点
ListNode *start = pre->next;
// 2. 翻转当前组的链表
ListNode* prev = nullptr;
ListNode* cur = start;
while(cur != nextGroup)
{
ListNode* temp = cur->next;
cur->next = prev;
prev = cur;
cur = temp;
}
// 3. 重新连接链表
pre->next = end; // 前驱节点连接翻转后的头节点
start->next = nextGroup; // 翻转后的尾节点连接下一组
// 4. 更新指针位置, 继续处理下一组
pre = start; // pre移动到下一组的前驱节点, 即当前组的尾结点
end = pre; // end同步移动
}
return dummy->next;
}
};
a.核心思想
通过分组翻转+指针重构实现链表每k个节点一组的翻转。核心在于精准定位每组边界,完成局部翻转后重新连接链表,同时处理不足k个节点的剩余部分直接保留。哨兵节点(dummy)简化头节点翻转的特殊逻辑,三指针法实现高效翻转。
b.思路
① 分组处理:将链表按k个节点分组,完整组翻转,不完整组保留。
② 指针定位:用
pre和end指针定位每组边界,翻转后重新连接。③ 原地操作:通过指针交换实现翻转,避免额外空间消耗。
c.步骤
① 初始化:添加哨兵节点(dummy)简化头节点处理,初始化
pre和end指针。② 定位组尾:移动
end指针k步定位当前组尾节点,不足k则直接返回。③ 记录节点:保存下一组起始位置和当前组起始节点。
④ 翻转链表:用三指针(cur, prev, temp)翻转当前组。
⑤ 重新连接:将翻转后的组与前驱和后继链表连接。
⑥ 指针迭代:更新
pre和end,处理下一组,直至链表结束。⑦ 返回结果:返回哨兵节点的下一节点作为新链表头。
2.C 编译到执行的4个阶段
a.预处理
预处理阶段通过预处理器(如
cpp)处理源代码中的预处理指令(如#include、#define、#ifdef等),展开头文件、替换宏定义、删除注释,最终生成一个纯 C 代码的文本文件(.i文件),为后续编译做准备。
b.编译
编译阶段将预处理后的代码转换为汇编代码,编译器(如
gcc)进行语法分析、语义分析和中间代码生成,最终输出特定架构的汇编指令文件(.s文件),这一步实现了从高级语言到低级汇编语言的转换。
c.汇编
汇编阶段由汇编器(如
as)将汇编代码翻译为二进制机器码,生成目标文件(.o或.obj),其中包含机器指令、符号表和待解析的外部引用,但尚未解决跨文件的函数或变量调用关系。
d.链接
链接阶段由链接器(如
ld)合并多个目标文件和库文件,解析符号引用(如函数或全局变量的地址绑定),整合代码段、数据段,最终生成可直接加载到内存执行的可执行文件(如a.out或.exe)。
希望这些内容对大家有所帮助!
感谢大家的三连支持!
更多推荐
所有评论(0)