力扣(链接放这里喽)
先贴代码再做讲解:
struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode* cur = head; struct ListNode* tail = NULL; while(cur) { if(cur->val == val) { if(cur == head) { head = head->next; free(cur); cur = head; } else { tail->next = cur->next; free(cur); cur = tail->next; } } else { tail = cur; cur = cur->next; } } if(tail) tail->next = NULL; return head; }
我们应该先将情况考虑周全,画图分析思路 :
我们假设有上述这种情况,按照题目设想,前面三个6都应该free掉,从3这个位置开始,也就是说我们要返回的头就从此处开始,所以我们先考虑值相等,过掉再继续。
在这个位置,要有一个继续往后走的指针,和保存头部位置的指针,以及一个保存尾部的指针来连接后面的5,因为head确定后就不会再动了,而遍历指针过掉中间的6时,3与5是不相接的,要连接只能说找尾指针。
还有第二种思路,就是值不相等就拿下来,值相等就跳过,free掉:
struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode* cur = head; struct ListNode* temp = NULL; struct ListNode* tail = NULL; while(cur) { if(cur->val == val) { temp = cur; cur = cur->next; free(temp); } else { if(tail == NULL) head = tail = cur; else { tail->next = cur; tail = cur; } cur = cur->next; } } if(tail) tail->next = NULL; if(tail == NULL) return NULL; return head; }