来源:leetcode,题目链接:
1.移除元素
2.合并两个有序数组
目录
移除元素
题目描述
解题思路
思路一:覆盖
思路二:以空间换时间
思路三:双指针
思路三代码实现
样例结果
合并两个有序数组
题目描述
解题思路
代码实现
样例结果
题目描述
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路一:覆盖
- 依次遍历数组中的每一个元素,当该元素=val时,将该元素之后的值向前移一位
- 该思路的时间复杂度是多少?
考虑最坏的情况,即一个数组中,大部分数据都是val,外层循环的时间复杂度为O(N),但在内部,还要逐个遍历循环,因此时间复杂度为O(N^2)
该方法的时间复杂度较大,我们进行代码优化,使其时间复杂度优化为O(N)
思路二:以空间换时间
创建一个新的数组专门存放不是val的数据
该思路只需要走一遍循环就可以得出最后结果,但由于创建了新的数组,牺牲了空间,空间复杂度为O(N)
继续思考:我们还可不可以继续进行代码优化,令其在时间复杂度不变的情况下,将空间复杂度优化为O(1)?
思路三:双指针
- 创建两个指针,src、dst。src遍历整个数组,dst存储不需要移除的元素。
- 两个指针的起始点均指向头部,src进行数组遍历
- 当nums[src] = val 时, nums[dst] = nums[src],src++,dst++
- nums[src] != val 时,src继续遍历,只让src++
int removeElement(int* nums, int numsSize, int val){
int src = 0;
int dst = 0;
while(src < numsSize) //确保在数组大小内循环
{
if(nums[src] != val)
{
nums[dst++] = nums[src++];
}
else
{
src++;
}
}
return dst ;
}
题目描述
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
int end = m+n-1;
int end1 = m-1;
int end2 = n-1;
while(end1 >= 0 && end2 >= 0)
{
if(nums1[end1] > nums2[end2])
{
nums1[end] = nums1[end1];
--end;
--end1;
}
else
{
nums1[end] = nums2[end2];
--end;
--end2;
}
}
//如果end1没结束,end2结束了,不需要处理,因为剩下的end1就在nums1里面
while(end2 >= 0)
{
nums1[end] = nums2[end2];
--end;
--end2;
}
今天的内容到这里就结束啦