算法小白,最近刷LeetCode。希望能够结合自己的思考和别人优秀的代码,对题目和解法进行更加清晰详细的解释,供大家参考^_^
19. Remove Nth Node From End of List
Given a linked list, remove the nth node from the end of list and return its head.
For 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. Try to do this in one pass.
题目让删除倒数第n个结点,最直接的解法是遍历列表,求出列表长度,进而得到被删除的结点位置,再进行一次遍历找到该结点进行删除。
上述方法需要进行两次遍历,题目要求只能使用一次,即one pass,因此需要新的方法。
我的思路来源于最近刷题经常碰到两个指针的情况,所有考虑使用两个指针,进而联想到,只要保证两个指针的距离为n-1, 当后一个指针移动到最后时,前一个指针刚好指向被删除的节点。
/**
* 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) {
ListNode *p1 = head, *p2 = head; // p1指向被删除的节点,使用p2进行遍历
ListNode *p3; // p3指向p1前面的结点
int count = 0;
while (p2 != NULL){
++count;
if (count > n) { // p1和p2的间距为n-1, 开始移动p1,同时记录p3
p3 = p1;
p1 = p1->next;
}
p2 = p2->next;
}
if(p1 == head) head = head->next;
else {
p3->next = p1->next;
}
return head;
}
};
由于当时没思考删除结点怎么做,将p1指向了被删除的结点,最后尴尬的发现需要一个指向前一个结点的指针,才能进行删除,于是增加了指针p3。
实际上应该将p1直接指向被删除结点的前一个结点,这样就可以使用p1->next = p1->next->next
进行删除了。