力扣刷题 - 203.移除链表元素
题目:
方法:创建一个新链表,遍历原链表找不为val的值,存放到新链表。
思路:在这里我们已经有了一个链表,我们要在链表中去实现删除指定值的节点,返回新的头节点。你会发现这道题其实和前面移除元素类似,那我们能不能用双指针去解决这道题呢?答案肯定是不行的,为什么呢?
前面移除元素的双指针是改变了值,但是空间大小并没有发生变化。但是在链表中我得把它所在的节点给删除,虽然道理类似,但是在链表这里行不通。
因此,我们创建一个新链表,新链表的话就得有新的头节点和尾节点!这是就有人问为什么要有尾节点,那肯定是因为我们链表是有始有终的,如果没有尾节点我们就不知道链表末尾的情况。
创建好之后,我们就开始遍历链表,找不为val的节点,存放到新链表。
这里注意:我们创建的链表最开始肯定是空链表,但当我们插入一个节点后,就不再是空链表了!所以我们需要分为两种情况去讨论:空链表/非空链表
当我们去执行时,系统告诉我们第一个样例不通过,这是为什么呢?
我们调试发现:
最后一个节点的next并不是NULL,所以需要特殊处理
即当newTail !=NULL时,newTail -> next = NULL;这里我们要注意newTail !=NULL,因为如果原链表为空链表时,newTail为空指针,空指针是无法解引用的!!!
代码:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {//第一步:创建一个新链表,需要头结点和尾结点ListNode* newHead=NULL;ListNode* newTail=NULL;ListNode* pcur=head;while(pcur){//第二步:遍历原链表找到不是val的值if(pcur->val!=val){//第三步:讨论链表为空和非空的情况//链表为空的情况if(newHead==NULL){newHead=newTail=pcur;}//链表非空的情况else{newTail->next=pcur;newTail=newTail->next;}}pcur=pcur->next;}if(newTail!=NULL)//如果newTail为空,空指针不能解引用,所以需要判断newTail->next=NULL;return newHead;
}