删除顺序表中为x的元素,保留其他元素,时间复杂度不超过O(n),空间复杂度不超过O(1)
设置k,k个保留元素放到新的顺序表A1,依次把元素插进A
1.k记录保留的元素个数
2.保留新的元素插入A1的物理位序
#define _CRT_SECURE_NO_WARNINGS 1
#include
//已知长度为n的线性表A采用顺序存储结构,
//编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,
//该算法删除线性表中所有值为x的数据元素。
//1.重建法
//重新设立一个顺序表,内部储存数据为除x外的有效数据
typedef int ElemType;
typedef struct Sqlist
{
ElemType length;
ElemType data[100];
}SqList;
void delnode1(SqList** A,ElemType x)
{
int k = 0, i;//k记录值不等于x的元素个数
for (i=0;i<(*A)->length;i++)
{
if ((*A)->data[i]!=x)//若当前元素不为x,将其插入新顺序表A中
{
(*A)->data[k] =(*A)->data[i];
k++;//不等于x的元素增加1
}
}
(*A)->length = k;
}
通过前后两个指针,第一个指针用于判断元素的值与x的关系
不为x则将快指针j的值传给i,为x则向后移动,不进行赋值操作
//2.快慢指针法
void delall(SqList* A, int x)
{
int i = 0, j;
while (i < A->length && A->data[i] != x)//找到第一个元素为x的位置i
i++;
for (j = i + 1; j < A->length; j++) // i+1 =< j < A->length
if (A->data[j] != x)
{
A->data[i] = A->data[j];
i++;
}
A->length = i;
}
通过将后面的非x元素前移,取代x
代码实现:
//3.移位法
void delnode2(SqList **A,ElemType x)
{
int p = 0, i = 0;
//p的含义:p为顺序表A中空出来的位置数目,后续保留元素前方的空位数,即前移位数
//①p记录删除元素个数②保留的新元素前移的位置数
while (i<((*A)->length))
{
if ((*A)->data[i]==x)//当元素值为x时p增加1
{
p++;
}
else
{
(*A)->data[i - p] = (*A)->data[i];//将当前元素不为x时,将其前移p个位置
}
i++;
}
(*A)->length -= p;//顺序表A的长度递减p
}
27. 移除元素
给你一个数组 nums
和一个值 val
,你需要原地移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1: 输入:nums = [3,2,2,3], val = 3 输出:2, nums = [2,2] 解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。 示例 2: 输入:nums = [0,1,2,2,3,0,4,2], val = 2 输出:5, nums = [0,1,4,0,3] 解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
int removeElement(int* nums, int numsSize, int val)
{
int left=0;
for(int i=0;i
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]示例 2:
输入:head = [], val = 1 输出:[]示例 3:
输入:head = [7,7,7,7], val = 7 输出:[]
思路与前面的题目大致相同,首先设立快慢指针,慢指针p,快指针q。其中p用来设置保存结果的链表,而q用来跨过值为val的节点
这里需要考虑几个问题,如果p最开始的值就为val值,那么需要考虑将头节点向后移动,删去首个节点
还需要考虑如果最后所有元素都迭代完毕了,最后剩下的一个尾结点的值是否为val
struct ListNode* removeElements(struct ListNode* head, int val)
{
if(head==NULL)
{
return NULL;
}
struct ListNode* p=head;
struct ListNode* q=p->next;
while(p->next!=NULL)
{
if(p->val==val)
{
head=q;
p=q;
q=q->next;
}
else if(q->val!=val)
{
p=p->next;
q=q->next;
}
else
{
q=q->next;
p->next=q;
}
}
if(p->val==val)
{
return NULL;
}
return head;
}