一、思路
1.
遍历链表,删除掉等于val的节点;但是删除掉当前节点,就不能把链表串起来了,所以需要一个prev指针,使链表不断开。(双指针)
2.
创建新的头节点,将原链表内不等于val的节点拿下来尾插。 但是每次拿下来尾插,在单链表中需要找尾,时间复杂度为 O(n²) ,效率太低。所以新添加一个尾指针,记录尾插后 链表的尾指针,可以将时间复杂度降为O(n)。
二、代码如下
思路一:
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* prev = NULL,* cur = head;
while(cur)
{
if(cur->val == val)
{
if(prev != NULL)
{
prev->next = cur->next;
free(cur);
cur = prev->next;
}
else
{
cur = head->next;
free(head);
head = cur;
}
}
else
{
prev = cur;
cur = cur->next;
}
}
return head;
}
**********这里面需要考虑到,当 prev == NULL 与 prev != NULL时的指针情况***********************
思路二:
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* new = NULL,* cur = head,*tail = NULL;
while(cur)
{
if(cur->val != val)
{
if(new == NULL)
{
new = tail = cur;
}
else
{
tail->next = cur;
tail = tail->next;
}
cur = cur->next;
tail->next = NULL;
}
else
{
struct ListNode* del = cur;
cur = cur->next;
free(del);
}
}
return new;
}
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
注意:
1.当尾插第一个与其他个时,要分开讨论.
2.当尾插完后,tail->next要置空。
否则在这种情况下,尾插完2后,最后一个6会释放掉,但是 2 节点的指针还是指向6,但6已经被释放,导致野指针。