原题链接https://leetcode.com/problems/remove-linked-list-elements/?tab=Description:
Remove all elements from a linked list of integers that have value val.
Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5
这题考的是链表操作,毫无疑问要用指针遍历链表的每一个元素。removeElements函数头中给出的参数head应该是指向链表首元素的指针,那么就可以采用head=head->next的方法移动指针遍历。这样我就有两种思路:一,用一个指针nextNode指向当前项的下一项,判断nextNode->val是否等于val,是的话就“跳过”这一项,即把当前元素的next指针改为指向下下个元素。二,新建一个lastNode指针作为“伪首元素”,它的next指向真正的链表首元素(也是head初始指向的地方),判断head->val是否等于val,是的话就“跳过”head指向的当前项,把lastNode的next指向当前项的下一项,不是的话就要用lastNode=lastNode->next移动指针,确保lastNode永远指向当前项的前一项。经过思考我决定采用第二种方法,因为第一种有一个问题,就是用nextNode的话无法判断首元素是否等于val,而且当链表只有一个元素时会出现问题。C++代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* lastNode = new ListNode(0);
lastNode->next = head;
ListNode* first = lastNode;
while(head != NULL) {
if(head->val == val) {
lastNode->next = head->next;
}
else lastNode = lastNode->next;
head = head->next;
}
//delete lastNode;
//lastNode = NULL;
first = first->next;
return first;
}
};
创建lastNode指针时使用的参数0没有特殊意义,只是为了满足构造函数。first指针用于保存伪首元素,因为lastNode后面是会移动的,函数最后返回的是伪首元素的next指针,也就是指向首元素。这段代码里有一句注释掉的delete语句,我原本是想释放lastNode使用的内存空间,但是会报一个runtime error:double free and corruption,double free的意思是重复释放内存。而且经过测试发现,是因为执行了lastNode=lastNode->next才导致error。这篇博文http://blog.csdn.net/hazir/article/details/21413833有介绍delete的作用是释放指针指向的对象使用的内存,但指针本身的内存不会释放,也就是说我的这个delete语句其实是释放了链表中的一个listNode元素,所以这个做法本身是有问题的,但我还是没看出来哪里有“重复释放内存”,因为我应该只用了一次delete(http://www.cnblogs.com/laipDIDI/articles/2173532.html有介绍几种不正确delete导致的错误)。哪位大神路过的话帮忙解答一下。