目录
实现(Runtime: 8 ms,Memory Usage: 7.8 MB)
不考虑空间释放(Runtime: 24 ms Memory Usage: 7.9 MB)
考虑空间释放(Runtime: 16 ms Memory Usage: 8.3 MB)
问题描述
Remove all elements from a linked list of integers that have value val.
删除链表中整数为val的元素。
举例说明
Input: 1->2->6->3->4->5->6, val = 6 Output: 1->2->3->4->5
思路
删除链表中的元素的一个思路是,找到被删除元素的前一个元素prev。被删除元素goal = prev->next,前一个元素prev的next指向被删除元素goal的next,prev->next=goal->next。最后删除goal指向的元素即可。
由于第一个元素前面没有元素,所以增加一个虚拟头节点dummyhead。
实现(Runtime: 8 ms,Memory Usage: 7.8 MB)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode *dummyhead = malloc(sizeof(struct ListNode));
dummyhead->val = 0;
dummyhead->next = head;
bool flag;
for (struct ListNode *prev = dummyhead; prev != NULL; prev =(flag==true)?prev: prev->next) {
flag = false;
if (prev->next!=NULL && prev->next->val == val) {
struct ListNode *goal = prev->next;
if (prev == dummyhead)head = head->next;
prev->next = goal->next;
goal->next = NULL;
free(goal);
goal = NULL;
flag=true;
}
}
free(dummyhead);
dummyhead = NULL;
return head;
}
创建bool变量flag的原因是,一旦删除元素之后进行prev=prev->next的操作就会跳过一个元素。例如删除【1 1 3】中的1,删除第一个元素后,dummyhead->1->3->NULL,prev指向dummyhead。 如果prev=prev->next,prev指向1以后,再次循环时判断的是prev->next->val是否等于val,这样就跳过了第二个元素判断第三个元素。
而这样做的弊端就是,如果删除最后一个元素,这之后prev始终在被删除元素的前一个元素。例如删除【5 6】中的6,删除最后一个元素6之后,prev始终指向5,等下一次判断prev->next->val==val时,就会报错member access within null pointer of type 'struct ListNode'。所以在if中增加一个条件是prev->next!=NULL ,这样prev会顺利指向NULL,退出循环.。
流程图如下:
递归实现
不考虑空间释放(Runtime: 24 ms Memory Usage: 7.9 MB)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
if(head==NULL)
return NULL;
head->next = removeElements(head->next,val);
return head->val == val? head->next:head;
}
考虑空间释放(Runtime: 16 ms Memory Usage: 8.3 MB)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
if(head==NULL)
return NULL;
head->next = removeElements(head->next,val);
if(head->val==val)
{
struct ListNode* goal = head->next;
free(head);
head = NULL;
return goal;
}
else
return head;
}