问题描述:
删除单链表中的倒数第 k 个元素,问题的难度在于单链表只能够进行单向访问。
https://oj.leetcode.com/problems/remove-nth-node-from-end-of-list/
点击打开链接
该题目和leetcode 中的单链表循环右移动可以归为同一类。
https://oj.leetcode.com/problems/rotate-list/
点击打开链接
问题分析:
1. p1 = p2 = head;
2. p1 先移动k步;
3. p1, p2 同时开始移动,p1移动到NULL的时候,p2移动到要删除的元素。
示例代码:
void delete_kth_from_tail(ListNode *head, int k)
{
if (!head) return;
ListNode *p1, *p2, *prv;
int i = 0;
p1 = p2 = head; prv = NULL;
for (;p1 && i < k; i++, p = p->next);
if (!p1) return; // invalid parameter k
for (;p1; p1 = p1->next, prv = p2, p2 = p2->next);
prv->next = p2->next->next;
delete p2;
}
leetcode 的代码如下:
ListNode *removeNthFromEnd(ListNode *head, int k)
{
if (!head) return NULL;
ListNode *p1, *p2, *prv;
int i = 0;
p1 = p2 = head; prv = NULL;
for (;p1 && i < k; i++, p1 = p1->next); /* move p1 k steps */
if (!p1 && i < k) return NULL; /* invalid parameter k */
for (;p1; p1 = p1->next, prv = p2, p2 = p2->next); /* move p1, p2 at the same time */
if (prv)
{ prv->next = p2->next; }
else
{ head = head->next;}
/* delete p2 */
return head;
}
和上面例子中的代码相比做的更正如下:
1. 非法参数的判断 if (!p1 && i < k) return NULL; /* invalid parameter k */
2. 删除链表首元素的检测
if (prv)
{ prv->next = p2->next; }
else
{ head = head->next;}