每日一练之移除链表元素
题目:
画图解析:
方法:双指针
解答代码(注:解答代码带解析):
//题目给的结构体
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
ListNode* removeElements(struct ListNode* head, int val) {
ListNode* newHead, * newTail;
newHead = newTail = NULL;
ListNode* pcur = head;
while (pcur)
{
if (pcur->val != val)
{
if (newHead == NULL)//链表的头结点没有找到
{
newHead = newTail = pcur;//找到新的链表的头结点newHead,这个头结点后面要传回去,不能动。
}
else//找到头结点之后这时候newHead和newTail都在头结点
{
newTail->next = pcur;//先存储pcur的地址
newTail = newTail->next;//再走下一步
}
}
pcur = pcur->next;//无论怎么样pcur都要走下一步,找到要移除的元素直接跳过就行
}
if (newTail)//这时候pcur=NULL;但是newTail->next没有改为NULL,链表不完整
{
newTail->next = NULL;
}
return newHead;
}
建议动手敲一敲!!
上面的代码是老师教的,下面分享我写的,我自己写的代码时间复杂度太高了,不建议模仿。
本人自己写的代码:
#define _CRT_SECURE_NO_WARNINGS 1
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
ListNode* removeElements(struct ListNode* head, int val) {
ListNode* newHead, * newTail, * phead;
if (head == NULL)
{
return head;
}
phead = head;
while (phead)//找新的头结点
{
if (phead->val != val)
{
newHead = phead;//只要不是移除元素,这个结点就是新的头结点,找到马上跳出循环
break;
}
phead = phead->next;
}
if (phead == NULL)
{
return NULL;
}
newTail = phead = newHead;
while (phead)
{
if (phead->val != val)
{
newTail = phead;
phead = phead->next;
}
else
{
ListNode* del = phead;
phead = phead->next;
newTail->next = phead;
free(del);
del = NULL;
}
}
return newHead;
}
完!!