算法1:给一个数组 nums 和一个值val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
实例:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5,nums = [0,1,3,0,4]
解释:函数应该返回新的长度5,并且nums中的前五个元素为0,1,3,0,4。注意这五个元素可为任意顺序。不需要考虑数组中超过新长度后面的元素。
思路1:逐个元素去找,但是这样时间复杂度会很高
思路2:以空间换时间,吧不是val的数据,放到新数组,再把新数组的值拷贝回来
思路3:设置快慢指针,src和dest,src位置不是val就放到dest位置,然后src++,dest++,src位置是val,src++
思路3代码:
int reverse(int* nums,int len,int val) {
int src = 0;
int dest = 0;
while (src < len) {
if (nums[src] != val) {
nums[dest] = nums[src];
src++;
dest++;
}
else
{
src++;
}
}
return dest;
}
int main() {
int arr[] = { 0,1,2,2,3,0,4,2 };
int k = 2;
int sz = sizeof(arr) / sizeof(arr[0]);
int dest = reverse(arr,sz,k);
for (int i = 0; i < dest; i++) {
printf("%d ", arr[i]);
}
return 0;
}
算法2:合并两个有序数组
给定两个有序整数数组 nums1 和 nums ,请将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2 的元素数量分别为 m 和 n ,可以假设nums1 的空间大小等于 m+n ,这样它就有足够的空间保存来自 nums2 的元素。
实例:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
思路:nums1和nums2都从后往前走,取大的从后往前放
代码
//提示数组越界访问就,但是能运行出来,还没发现问题出在哪里
void reverse(int* nums1,int m,int* nums2,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];
end1--;
end--;
}
else {
nums1[end] = nums2[end2];
end2--;
end--;
}
}
//如果end1没完不需要再处理,因为本身就是再end1中操作
//而end2没处理完,就需要继续将end2中的直接挪到end1前边
while (end2>=0){
nums1[end] = nums2[end2];
end2--;
end--;
}
}
int main() {
int nums1[] = { 1,2,3};
int nums2[] = { 2,5,6 };
int m = sizeof(nums1) / sizeof(nums1[0]);
int n = sizeof(nums2) / sizeof(nums2[0]);;
reverse(nums1,m,nums2,n);
for (int i = 0; i < m + n; i++) {
printf("%d ", nums1[i]);
}
return 0;
}