题目
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
思路
在第一个节点前创建一个虚拟头节点,便于对节点的删除
代码
//如何定义一个节点
// typedef struct ListNodeT {
// int val;
// struct ListNodeT next;
// } ListNode;
// struct ListNode {
// int val; // 节点上存储的元素
// ListNode *next; // 指向下一个节点的指针
// ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
// };
struct ListNode* removeElements(struct ListNode* head, int val) {
typedef struct ListNode ListNode;
ListNode *dummy; //创建虚拟头结点
dummy = (ListNode*)malloc(sizeof(ListNode)); //到现在也不太懂这一步的意义
dummy -> next = head; //虚拟头结点指向原head
ListNode *cur = dummy; //用于遍历链表的指针
//下面是另一种定义虚拟头节点的方式,不是,为什么这里又是“cur = &dummy”啊,这个&我分不清,真的分不清啊!!!
struct ListNode dummy = {0 ,head};
struct ListNode* cur = &dummy;
while (cur -> next != NULL){ //遍历至最后一个节点
if(cur -> next -> val == val){
ListNode *tmp = cur -> next; //指向要删除的节点的指针(c的指针真妙啊)
cur -> next = cur -> next -> next; //将此节点上一个节点指向下下个)
free(tmp); //释放此节点
}else{
cur = cur -> next; //继续遍历
}
}
head = dummy -> next;
free(dummy);
return head; //返回的为dummy.mext,因为原来的head可能被替换了
}
总结:
1.再复习复习链表的定义使用吧,基础知识没过关,这题写起来跟挤牙膏一样就当纯学思路;
(两天后的我:咦!好!我懂了。还是得多动手敲代码,使用或忘记!)
2.注意单链表只能从前往后查找,所以要删除某节点要将此节点前一个节点的next指向此节点下一个节点;
3.返回的应该是修改后的新头结点;