思路:遍历寻找到val值所在节点,将上一个节点的next指针指向非val值所在节点。
初始代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
//个人偏向于使用虚拟头节点(虚拟头节点指向题目中给的头节点)
typedef struct ListNode LNode;
LNode* virtualNode = (LNode*)malloc(sizeof(LNode));
virtualNode -> next = head;//虚拟头节点的next指向head头节点
LNode* moveNode = virtualNode;
while(moveNode){//当moveNode != NULL时,往后寻找
LNode* temNode = moveNode;//用来记录所查元素的前一个节点的地址
moveNode = moveNode -> next;//moveNode移向所查节点
while(moveNode && moveNode -> val == val) {//循环查元素,直到所指节点的值不等于题目所给整数值
LNode* freeNode = moveNode;
moveNode = moveNode -> next;
free(freeNode);//别忘了free掉不要的节点呀!!
}
temNode -> next = moveNode;//连上
}
return virtualNode -> next;
}
这段代码存在的问题是太冗长,且耗时跟内存消耗的数据都不好看。
改进代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
//个人偏向于使用虚拟头节点(虚拟头节点指向题目中给的头节点)
typedef struct ListNode LNode;
LNode* virtualNode = (LNode*)malloc(sizeof(LNode));
virtualNode -> next = head;
//LNode* moveNode = virtualNode;不要moveNode了,让head自己移动
head = virtualNode;//让head等同于虚拟头节点
/*下面这段太冗长!
while(head){
LNode* temNode = head;
head = head -> next;
while(head && head -> val == val) {
LNode* freeNode = head;
head = head -> next;
free(freeNode);
}
temNode -> next = head;
}
*/
while(head -> next){//思路略微不一样的是当没找到应该接的下个节点时不移动head,省去了记录删去节点的前一个节点
while(head -> next && head -> next -> val == val) {
LNode* freeNode = head -> next;
head -> next = head -> next -> next;
free(freeNode);
}
if(head -> next) head = head -> next;
}
return virtualNode -> next;
}
耗时改进了蛮多,但是内存消耗就只改进了一点点......