List · leetcode-19 删除倒数第n个节点
题面
删除倒数第n个节点,可以保证给定的n有效。
样例
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
思路
这个题,挺经典的题目。我们使用快慢指针解决,即:一个指针先行n, 之后另一个指针跟它一起走,直到后面的指针到链表尾部,结束,返回结果。
分析样例
n = 2
1(p, q)->2->3->4->5 (初始化p, q)
1(p)->2(q)->3->4->5 (q后移)1(p)->2->3(q)->4->5 (此时q已经后移2个节点,做判断,如果为空,那么就删除p节点)1->2(p)->3->4(q)->5 (一起后移)1->2->3(p)->4->5(q) q已经到达尾部,结束。我们可以看到p就是我们要删除的倒数第二个4节点的前驱节点,删除p->next节点)
算法
1. 双指针p, q初始化为head;
2. q 后移n个结点,判断是否到达链表尾部,如果到达,那么代表要删除的就是当前p即head;;否则,3
3. p,q同步后移,直到q到达尾部,删除p->next即可。
源码
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* removeNthFromEnd(ListNode* head, int n) { 12 //快慢指针实现删除倒数第n个节点 13 if(head == nullptr) 14 return nullptr; 15 ListNode* p = head, *q = head; 16 while(n--) 17 q = q->next; 18 if(q == nullptr) 19 return head->next; 20 21 while(q->next != nullptr) 22 { 23 p = p->next; 24 q = q->next; 25 } 26 ListNode* tmp = p->next; 27 p->next = tmp->next; 28 delete tmp; 29 30 return head; 31 } 32 };