一.移除数组元素
当看到这个题目时,我们首先应该会想到再创建一个数组,将原数组中的值对val进行遍历,将其得到的值转移到新数组中,但是这题对数组空间有额外的空间限制,所以我们需要另一种想法。
双变量检测
在这里,我们可以尝试利用双变量src和dst对原数组进行检测
假设数组里面是3223这几个数,如果我们想要删除vall = 3,我们就用
1.src和dst初始都指向初始值3
2.接下来进行检测,如果src指向val,则src++,如果src不指向val,则将arr[src]直接赋值给arr[dst],这样可以让我们需要的数据将不需要的数据直接覆盖,数组长度减少
3.这样,我们可以知道,新数组的有效长度为dst
于是,我们将思路写成代码:
int removeElement(int* nums, int numsSize, int val) {
int src,dst;
src = dst = 0;
while(src < numsSize)
{
if(nums[src] == val)
src++;
else
{
nums[dst] = nums[src];
src++;
dst++;
}
}
return dst;
}
这里的numsSize是原数组的总长度,这样,这题就做完了!
二.数组合并
这里,我们有两种思路,最简单的是将第二个数组直接插入第一个数组后面,再直接进行排序,但如果要进行排序,那么时间复杂度必然会较高,所以,我们使用变量检测的方法。
三变量检测
(初始)
(末尾)
在这里,我们定义三个变量l1,l2,l3,先将l1指向的值与l2将比较,谁的值大谁就将值放到l3,而如果从前向后比较会出现前面数据把后面数据覆盖的情况,导致数据丢失,所以这里我们选择变量从后往前移动。
两种特殊情况
但在这里,我们还会遇到,l2已经离开循环,但l1仍然没有移动的情况,如果num1刚开始里面的值很小的话,l1将不会移动,但题目告诉我们,num1是有序的非递减数组,所以我们不用考虑这种情况。
当l1已经离开循环,l2还没有离开时,我们可以直接循环地将num2中的值放到l1中,于是,我们将思路实现成代码:
void merge(int* nums1, int m, int* nums2, int n) {
int l1 = m - 1;
int l2 = n - 1;
int l3 = m + n - 1;
while(l1 >= 0 && l2 >= 0)
{
if(nums1[l1] < nums2[l2])
{
nums1[l3--] = nums2[l2--];
//l3--;
//l2--;
}
else
{
nums1[l3--] = nums1[l1--];
}
}
//出循环后有两种情况:l1<0或l2<0
//只需处理l2>=0,
while(l2 >= 0)
{
nums1[l3--] = nums2[l2--];
}
}
这样,我们的代码就完成了!