面试题02.02

思路
这个题的解法就是非常简单的快慢指针,不过这次我们不用不同速度的两个指针。题目要求的是返回倒数第k个节点,那么我们就让快指针fast比慢指针slow先走k步,那么当快指针fast到达链表末尾的时候,此时slow正好位于倒数第k个节点,直接返回slow即可得到倒数第k个节点。
代码
class Solution {
public:
int kthToLast(ListNode* head, int k) {
ListNode* slow = head;
ListNode* fast = head;
for (int i = 0; i < k; i++) {
fast++;
}
while (fast) {
slow++;
fast++;
}
}
};
知识点复习
for循环和while循环的区别
| 语法结构 | for(初始化; 条件; 更新) 三者集中在头部 | 初始化在循环外,条件在 while 后,更新需手动写在循环体内 |
| 典型代码 | for(int i=0; i<10; i++){…} | int i=0; while(i<10){… i++;} |
| 适用场景 | 已知循环次数 | 循环次数未知,已知循环结束条件 |
| 代码紧凑度 | 高,循环要素集中一处,易读 | 低,要素分散,容易漏写更新语句 |
| 变量作用域 | for(int i=…) 的 i 仅限循环内,外部不可访问 | 循环变量定义在外部,循环结束后仍可使用 |
| 能否省略表达式 | 三个表达式均可省略,for(;;) 为死循环 | 无条件则无法形成循环(需结合 break) |
| 执行流程 | 初始化 → 判断 → 执行体 → 更新 → 判断… | 判断 → 执行体 → 判断…(初始化在循环外) |
注:代码中的while(fast)等价于while(fast!=nullptr)
面试题02.03.删除中间节

思路
把下一个节点的值拷贝到当前节点,当前节点的 next,直接跳过下一个节点,指向 next->next
🤔相当于:用后继节点覆盖自己,删掉后继节点,伪装成把自己删掉。
代码
class Solution {
public:
void deleteNode(ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
}
};
如下图:

| 需要待删节点的前驱节点 | 只需要待删节点本身 |
| 修改前驱的 next 指针 | 复制后继的值,修改本节点 next |
| 可以删头、中间、尾节点 | 只能删中间节点,不能删尾 |
