思路1:以空间换时间,将数组nums中数值不等于cal的元素放在新数组nums2中,全部移动完毕后,再将新数组的值拷贝回nums中。但这种方法时间、空间的复杂度都为O(N),效率不高。
思路2:双下标覆盖。设定两个下标为src和dst,位置为数组的起始位置0,当src所指向的值不等于cal时,则将下标src的数组元素的值赋给下标dst的数组元素的值,两个下标分别自增;当nums[src]的值等于cal时,src自增。直到src的值等于numsSize,停止,此时下标dst的值就等于移除cal的值后数组的长度。时间复杂度为O(N),空间复杂度为O(1)。
代码实现:
//numsSize为数组内元素的个数
int removeElement(int* nums, int numsSize, int val)
{
int src = 0;
int dst = 0;
//下标src需要经过数组内所有的元素
while (src < numsSize)
{
if (nums[src] != val)
{
nums[dst++] = nums[src++];
}
else
{
src++;
}
}
return dst;
}
void Print(int* nums, int a)
{
for (int i = 0; i < a; i++)
{
printf("%d ", nums[i]);
}
printf("\n");
}
int main()
{
int nums[] = { 1,2,3,4,2,2,5,8,9 };
int val = 2;
int numsSize = 0;
int a = 0;
numsSize = sizeof(nums) / sizeof(nums[0]);
a = removeElement(nums, numsSize, val);
Print(nums, a);
printf("%d\n", a);
return 0;
}
运行结果: