1.移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
对于给定的链表,首先对除了头节点head 以外的节点进行删除操作,然后判断head 的节点值是否等于给定的 val。如果head 的节点值等于 val,则 head 需要被删除,因此删除操作后的头节点为 head.next;如果head 的节点值不等于val,则head 保留,因此删除操作后的头节点还是 head。上述过程是一个递归的过程。
递归的终止条件是 \textit{head}head 为空,此时直接返回 \textit{head}head。当 \textit{head}head 不为空时,递归地进行删除操作,然后判断 \textit{head}head 的节点值是否等于 \textit{val}val 并决定是否要删除 head。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
//递归,时间空间0(n),O(n)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head==NULL)return head;
head->next=removeElements(head->next,val);
if(head->val==val)
{
return head->next;
}
else
{
return head;
}
}
};
迭代,时间空间O(n),O(1)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode*dummy=new ListNode(-1);
dummy->next=head;
ListNode*cur = dummy;
while(cur->next)
{
if(cur->next->val==val) //也可移除值在某一区间的,比如大于1小于5的点,改判断条件即可
{
ListNode*p=cur->next;
cur->next=p->next;
delete p;
}
else
{
cur=cur->next;
}
}
return dummy->next;
}
};
/*1.head为带头结点的链表
2.先创建工作指针指向head,利用循环判断其下一节点是否为指定节点若是则进行删除,若不是则将工作指针指向下一节点。
ListNode*remove(ListNode*head,int val)
{
//创工作指针
ListNode*cur=head;
while(cur->next)
{
if(cur->next==val)
{
ListNode*p=cur->next;
cur->next=p->next;
delete(p);
}
else
{
cur=cur->next;
}
}
return head;
}*/
2.删除链表中最小值节点(最小值唯一)
O(n) O(1);
代码
算法思路:
1: 申请一个指针min,用于指向最小值节点,minPrep指针指向min的前驱结点
2: 遍历链表,当出现更小值的时候就更新min,minPrep
3: 利用minPrep对minp的删除
class Solution {
public:
ListNode* deleteMin(ListNode* head) {
ListNode*dummy=new ListNode(-1);
dummy->next=head;
ListNode*minPre=dummy;
ListNode*min=dummy->next;
ListNode*curPre=dummy;
ListNode*cur=dummy->next;
while(cur)
{
if(cur->val<min->val)
{
min=cur;
minPre=curPre;
}
curPre=cur;
cur=cur->next;
}
minPre->next=min->next;
delete min;
return dummy->next;
}
};
/*
head为头结点指针
ListNode*deleteMin(ListNode*head)
{
//工作指针和其前驱
ListNode*cur=head->next;
ListNode*curPrep=head;
//最小值节点指针和其前驱
ListNode*min=head->next;
ListNode*minPrep=head;
while(cur)
{
if(cur->val<min->val)
{
min=cur;
minPrep=curPrep;
}
curPrep=cur;
cur=cur->next;
}
minPrep->next=min->next;
delete(min);
return head;
} */
3.将最小节点移到头结点后
代码
//带头指针
ListNode*yi(ListNode*A)
{
ListNode*cur=A->next;
ListNode*min=A->next;
ListNode*minPrep=A;
ListNode*curPrep=A;
while(cur)
{
if(min->val>cur->val)
{
min=cur;
minPrep=curPrep;
}
curPrep=cur;
cur=cur->next;
}
minPrep->next=minPrep->next->next;
min->next=A->next;
A->next=min;
return A;
}
4.删除排序链表中的重复元素(I)
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
输入:head = [1,1,2]
输出:[1,2]
输入:head = [1,1,2,3,3]
输出:[1,2,3]
时间复杂度
循环了一次链表,时间复杂度为O(n)
空间复杂度
O(1)
代码:
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode*duyy = head;
while(duyy!=NULL)
{
if(duyy->next!=NULL&&duyy->val==duyy->next->val)
{
duyy->next=duyy->next->next;
}
else
{
duyy=duyy->next;
}
}
return head;
}
};
手动变成带头结点的算法
class Solution {
public:
//head是带头结点的链表
ListNode* deleteDuplicates(ListNode* head) {
ListNode*duyy=head->next;
while(duyy!=NULL)
{
if(duyy->next!=NULL&&duyy->val==duyy->next->val)
{
ListNode* q=duyy->next;
duyy->next=q->next;
delete q;
}
else
{
duyy=duyy->next;
}
}
return head;
}
};