当前位置:网站首页>【C语言】LeetCode27.移除元素
【C语言】LeetCode27.移除元素
2022-07-31 15:53:00 【阿亮joy.】
移除元素
描述:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例 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。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
前情提醒: 对于本道题目,博主将给出三种解题的思路,三种思路由劣到优。因为我们都不可能一下子就想到最优的算法,这是需要慢慢练习的,话不多说直接开整。
思路一
找到所有的val,依次向前挪动数据覆盖删除。

代码示例:
#include <stdio.h>
int removeElement3(int* nums, int numsSize, int val)
{
int begin = 0;
int n = numsSize;
while (begin < n)
{
if (nums[begin] == val)
{
for (int i = begin + 1; i < n; i++)
{
nums[i - 1] = nums[i];
}
n--;//有元素的值为val,往前覆盖,元素个数减一
}
else
{
begin++;
}
}
return n;
}
int main()
{
int arr[6] = { 1,3,3,4,3,5 };
int len = removeElement3(arr, 6, 3);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
return 0;
}输出结果:

分析:时间复杂度为O(N^2),最坏情况:数组中大部分值甚至全部都是val,空间复杂度为O(1)。该方法能够通过LeetCode的测试,但是时间复杂度过高,不是很好的方法。
思路二
用空间换取时间,一次遍历数组nums,把不是val的值,放到数组temp,再把数组temp的值拷贝回去。

代码示例:
#include <stdio.h>
#include <string.h>
int removeElement2(int* nums, int numsSize, int val)
{
int temp[numsSize] = {0};
int i = 0;
int count = 0;
for (i = 0; i < numsSize; i++)
{
if (nums[i] != val)
{
temp[count] = nums[i];
count++;
}
}
memcpy(nums, temp, sizeof(int) * count);
return count;
}
int main()
{
int arr[6] = { 1,3,3,4,3,5 };
int len = removeElement2(arr, 6, 3);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
return 0;
}输出结果:

分析:时间复杂度为O(N),空间复杂度为O(N),不满足题目要求的空间复杂度为O(1)。
思路三
利用双指针的思想,定义两个整型变量src和dst,src去找nums数组中不等于val的值,放到dst指定的位置去,在src++,dst++。

代码示例:
#include <stdio.h>
int removeElement1(int* nums, int numsSize, int val)
{
int src = 0;
int dst = 0;
while (src < numsSize)
{
if (nums[src] != val)
{
nums[dst] = nums[src];
src++;
dst++;
}
else
{
src++;
}
}
return dst;
}
int main()
{
int arr[6] = { 1,3,3,4,3,5 };
int len = removeElement1(arr, 6, 3);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
输出结果:

分析:时间复杂度为O(N),空间复杂度为O(1),该方法已经是这道题目的最优解了。可以学习一下这个思路。
以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家啦!
结语
每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根。
边栏推荐
- Applicable Scenarios of Multi-Master Replication (1) - Multi-IDC
- Premiere Pro 2022 for (pr 2022)v22.5.0
- 删除表格数据或清空表格
- Unity中实现点选RenderTexture中的3D模型
- leetcode303 Weekly Match Replay
- How does automated testing create business value?
- SIGABRT 报错时的注意事项和解决方法
- 字符串反转的实现方法总结「建议收藏」
- 网站漏洞修复服务商关于越权漏洞分析
- tooltips使用教程(鼠标悬停时显示提示)
猜你喜欢

Graham's Scan method for solving convex hull problems

Premiere Pro 2022 for (pr 2022)v22.5.0

6-22 Vulnerability exploit - postgresql database password cracking

使用 GraphiQL 可视化 GraphQL 架构

What is the difference between BI software in the domestic market?

C语言-函数

11 pinia使用

C语言”三子棋“升级版(模式选择+AI下棋)

gerrit中如何切换远程服务器

i.MX6ULL驱动开发 | 33 - NXP原厂网络设备驱动浅读(LAN8720 PHY)
随机推荐
Kubernetes common commands
C语言”三子棋“升级版(模式选择+AI下棋)
基于C语言的编译器设计与实现
字符串反转的实现方法总结「建议收藏」
6-22 Vulnerability exploit - postgresql database password cracking
全新宝马3系上市,安全、舒适一个不落
长得很怪的箱图
Implementing click on the 3D model in RenderTexture in Unity
ML.NET related resources
MySQL数据库操作
苹果官网样式调整 结账时产品图片“巨大化”
双边滤波加速「建议收藏」
org.apache.jasperException(could not initialize class org)
Delete the disk in good condition (recovery partition)
百度网盘网页版加速播放(有可用的网站吗)
JVM参数解析 Xmx、Xms、Xmn、NewRatio、SurvivorRatio、PermSize、PrintGC「建议收藏」
[MySQL] Mysql paradigm and the role of foreign keys
MySQL的相关问题
复制延迟案例(3)-单调读
radiobutton的使用