给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点
这里主要注意删除头结点与删除其它节点的方法不同,还要注意的是释放空间,C/C++没有自动内存管理,所以要手动删除养成好习惯,防止内存泄露
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head==NULL)return head;
//删除头结点
while(head!=NULL && head->val==val)
{
ListNode* temp=head;
head=head->next;
delete temp;
}
//删除其余节点
ListNode* cur=head;
//注意这里要加cur!=NULL,因为如果全是目标元素可能会删完这里要判空一下
while(cur!=NULL && cur->next!=NULL)
{
if(cur->next->val==val)
{
ListNode* temp=cur->next;
cur->next=cur->next->next;
delete temp;
}
else
{
cur=cur->next;
}
}
return head;
}
};
这是迭代的思路
时间复杂度 O(n) 空间复杂度O(1)
还有递归思路
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//访问到最后一个元素的下一个元素时的递归出口
if(head==nullptr)
{
return head;
}
//注意head->next=removeElements()head->next指向下一层递归的返回值
head->next=removeElements(head->next,val);
return head->val==val?head->next:head;
}
};
时间复杂度 O(n) 空间复杂度O(n)
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
思路我们使用cur记录当前节点,我们要使当前节点指向前一节点,这时候我们要引入pre前驱节点,当我们cur->next=pre后发现原本的cur->next丢失了,所以我们还要引入一个suc后继结点
继续遍历,这其实也就是双指针法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur=head;//当前节点
ListNode* pre=NULL;//前驱节点
ListNode* suc=NULL;//后继结点
while(cur)
{
suc=cur->next;
cur->next=pre;
pre=cur;
cur=suc;
}
return pre;
}
};
时间复杂度 O(n) 空间复杂度O(1)