数据结构与算法2:顺序表(算法题目)

这篇博客探讨了两种算法问题:一是如何在原地移除数组中特定值的元素,二是如何合并两个有序数组。对于第一种情况,提出了使用快慢指针的方法来达到O(1)额外空间的要求。第二种情况则通过双指针从后往前比较,将较大元素放入目标数组,确保结果有序。这两种方法都是在限制内存使用的情况下优化数组操作的有效策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值