版权声明:由于一些问题,理论类博客放到了blogger上,希望各位看官莅临指教https://efanbh.blogspot.com/;本文为博主原创文章,转载请注明本文来源 https://blog.csdn.net/wyf826459/article/details/81941532
题目描述:
Given a linked list, remove the n-th node from the end of list and return its head.
Example:
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.
Follow up:
Could you do this in one pass?
算法实现:
题目中要求我们一次遍历实现(Could you do this in one pass?),若无此条件,实现非常简单
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head == NULL) return NULL;
int length = 1;
ListNode* P = head;
while(P->next != NULL){
P = P->next;
length ++;
}
int suanz = length - n;
if(suanz == 0)return head->next;
int i = 1;
P = head;
while(i < suanz){
P = P->next;
i ++;
}
P->next = P->next->next;
return head;
}
};
如今要求我们通过一次遍历就实现功能,可以考虑建立两个指针,其指向的两个数固定相差n个位置,如此可以通过判断后一个指针是否为尾节点来判断是否到达要删除节点处。具体算法如下:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head == NULL) return NULL;
ListNode* P = head;
ListNode* Pn = head;
//建立了两个相差n个位置的指针,后一个指针为空时,前一个指针指向要被删除元素的位置
for(int i = 0; i < n; i ++)Pn = Pn -> next;
if(Pn == NULL)return head -> next;
while(Pn->next != NULL){
Pn = Pn -> next;
P = P -> next;
}
P->next = P->next->next;
return head;
}
};