1.第一题(移除元素)
先将第一题的链接附上
https://leetcode.cn/problems/remove-element/description/
拿到题我们先分析,首先不能使用额外的数组空间,那就是只能在原数组上操作;
其次元素顺序可以改变,说明我们不用考虑排序的问题,加上只能原地修改数组我们可以考虑使用双指针,然后画图分析(很关键)。
- 首先创建两个指针 src dst
- 然后思考其运行条件,当src走到数组最后一个时结束
- 当nums[src] != val时将nums[src] 的值传给nums[dst](nums[dst]==nums[src]),dst++,src++
- 当nums[src] == val时src++,dst不动。
- 返回dst就是返回到新的数组长度。
完整代码如下:
int removeElement(int* nums, int numsSize, int val) {
int src = 0;
int dst = 0;
//当src小于数组的最后一个下标时运行
while (src < numsSize)
{
//当src所指向的值不等于val时,将src所指向的值传给dst
if (nums[src] != val)
{
nums[dst] = nums[src];
dst++;
src++;
}
//当src所指向的值等于val时,src++向后移动继续寻找
else
{
src++;
}
}
//返回数组新长度
return dst;
}
2.第二题
26. 删除有序数组中的重复项 - 力扣(LeetCode)
分析:
- 依然可以使用两个指针 fast slow 通过错位比较完成
- nums[fast]指向数组外时结束
-
当fast所指向的值不等于slow所指向的值时,先++指向下一个位置再将fast的值传给slow,slow++,fast++
-
然后 return slow + 1
完整代码如下:
int removeDuplicates(int* nums, int numsSize){
int slow = 0;
int fast = 1;
//当fast指向数组外时结束
while(fast < numsSize){
//当fast所指向的值不等于slow所指向的值时,先++指向下一个位置再将fast的值传给slow,slow++,fast++
if(nums[fast] != nums[slow])
{
slow++;
nums[slow] = nums[fast];
fast++;
}
else
{
fast++;
}
}
return slow + 1;
}
3.第三题
分析:
通过分析题目可知,我们可以使用暴破,双指针+额外存储空间来完成该题,但是这两种做法的空间和时间复杂度至少都是 O(m+n)。我们可以考虑 原地修改 ,将空间复杂度降低到 O(1)。
因为这样不需要使用额外的数组空间了,我们完全可以把 nums2 也放入 nums1中。
原地修改时,为了避免从前往后遍历导致原有数组元素被破坏掉,我们要选择从后往前遍历!
所以,我们总共需要创建三个指针,两个指针用于指向 nums1 和 nums2的初始化元素数量的末位,也就是分别指向 m−1 和 n−1的位置,还有一个指针,我们指向 nums1 数组末位即可。
依次比较取大的尾插。
完整代码:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
int end1=m-1;
int end2=n-1;
int end=m+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--;
}
}
while(end2>=0)
{
nums1[end]=nums2[end2];
end--;
end2--;
}
}
以上就是我对这些题的思路解法,如有不对不妥之处,有更好的思路的欢迎大家在评论区交流。