题目描述:
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点
方法一: 从头开始遍历链表,当遇到相同元素则跳过该元素,指向下一节点
- struct ListNode* removeElements(struct ListNode* head, int val) {
- if(head == NULL)
- return NULL;
-
- struct ListNode* cur = head;
- struct ListNode* prev = NULL;
-
- while(cur)
- {
- //如果当前节点是需要删除的节点
- if(cur->val == val)
- {
- //首先保存下一个节点
- struct ListNode* next = cur->next;
- //如果删除的为头节点,更新头节点
- //否则让当前节点的前趋节点链接next节点
- if(prev == NULL)
- {
- head = cur->next;
- }
- else
- {
- prev->next =next;
- }
- //释放当前节点,让cur指向next
- free(cur);
- cur = next;
- }
- else
- {
- //如果cur不是需要删除的节点,则更新prev,cur
- prev = cur;
- cur = cur->next;
- }
- }
-
- return head;
- }
这里要特别注意一种情况,当结点就为要删除的元素时,记得要更新头节点,由于我们会释放掉结点,不更新头结点会返回一个野指针
方法二: 定义一个新链表,依次尾插与val不同的结点
-
- struct ListNode* removeElements(struct ListNode* head, int val) {
- struct ListNode* newnode=NULL,*tail=NULL;
- struct ListNode* cur=head;
- while(cur)
- {
- if(cur->val!=val)
- {
- //插入第一个结点要特殊判断
- if(tail==NULL)
- {
- newnode=tail=cur;
- }
- else
- {
- tail->next=cur;
- tail=tail->next;
- }
- cur=cur->next;
- }
- else
- {
- //删除当前节点,cur向后走
- struct ListNode* tmp=cur;
- cur=cur->next;
- free(tmp);
- }
- }
- if(tail)
- tail->next=NULL;
-
- return newnode;
- }
本题中,tail始终指向新链表的末尾,便于尾插操作,插入元素时要先判断是否为第一个元素,即当尾指针tail为空时,新链表为空,这时需要将newnode和tail指向尾插的第一个结点,最后记得把尾指针置空,防止其指向野指针