力扣-19-删除链表倒数第N个结点/《剑指Offer》-22-链表中倒数第K个节点
可以看出,《剑指Offer》-22是力扣-19的子问题
找到链表中倒数第K个节点
《剑指Offer》-22,一次遍历单向链表得到倒数第K个结点的方法
从1开始倒数,那么倒数第K个节点即是正数第N-K+1个节点
这里还是使用同向双指针的办法
pointer1/pointer2都初始化为指向0,pointer1先开始走而pointer2不动,当pointer1走完第K-1步后,pointer2开始同步pointer1往后走,这样始终保持了两个指针间距为K-1
则最终,当pointer1指向第N个节点时,pointer2指向的便是第N-K+1个节点,即倒数第K个节点
代码实现
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* temp = new ListNode(0,head); ListNode* pointer1=head; ListNode* pointer2=temp; // 这里不需要做检查,n一定是合法的 for(int i=0;i<n;++i){ pointer1 = pointer1->next; } // 移动 while(pointer1){ pointer1=pointer1->next; pointer2=pointer2->next; } pointer2->next=pointer2->next->next; ListNode* ans = temp->next; delete temp; return ans; } };
也可以原始一点,直接跑两次循环,第一次得到n,第二次再跑n-k+1就是结果
ListNode* getKthFromEnd(ListNode* head, int k) { // 倒数第k个,那么就是正数第…但是又不知道这个链表的长度不是 // 知道了n其实就很容易了,正数:n-k+1个位置 int count = 0; ListNode* ptr = head; while (ptr) { count++; ptr = ptr->next; } ptr = head; for (int i = 0; i < count - k; i++) { ptr = ptr->next; } return ptr; }
官方题解
初级算法里面所谓的“Dummy node”节点技巧就是添加一个指向头节点的节点,目的是为了解决头节点被操作的情况(例如被删了)
《剑指Offer》官解
书中给出的解法关注重点其实是在于代码的鲁棒性,也就是说考虑意外情况:
- 头指针为空
- k 的长度会不会大于链表长度
- k 有没有可能为 0
但事实上大多数时候我们关注的都是解题的思路和技巧,对于非法情况和输入,一般不影响到代码运行都默认没问题
ListNode* getKthFromEnd(ListNode* head, int k) { if (!head || !k) return nullptr; ListNode* pre = head; for (int i = 0; i < k - 1; i++) { if (pre->next) pre = pre->next; else return nullptr; } ListNode* res = head; while (pre) { pre = pre->next; res = res->next; } return res; }
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/16350236.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步