栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言刷题(三)——LeetCode数组篇(初级)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言刷题(三)——LeetCode数组篇(初级)

LeetCode——数组篇(初级)

1.给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

输入: nums = [0,1,0,3,12]

输出: [1,3,12,0,0]

解题思路:通过交换第一个0跟第一个非0的元素的位置达到把非零的往前移动。

[0,1,0,3,12] --> 出现0,且1不为0,所以将1跟0换,从而[1,0,0,3,12],往后,再找到3跟第一个0交换,再往后找到12跟3后面的0换从而得到[1,3,12,0,0]

void moveZeroes(int* nums, int numsSize)
{
	int count = 0;
	for (int i = 0; i < numsSize - 1; i++)
	{
		if (nums[i] == 0 && nums[i + 1] == 0)
		{
			count++;
		}else if (nums[i] == 0 && nums[i+1] != 0) {
				int temp = nums[i - count];
				nums[i - count] = nums[i + 1];
				nums[i + 1] = temp;
		}
	}

}

运行结果: 

2.给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素.

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

思路:跟题1的解题思路一样,将val值设置为0即可;

int removeElement(int* nums, int numsSize, int val){
    
	int count = 0;
    int c = 0;
for (int i = 0; i < numsSize; i++)
	{
		if (nums[i] == val)
		{
			nums[i] = 0;
			count++;
		}
	}
	for (int i = 0; i < numsSize - 1; i++)
	{
		if (nums[i] == 0 && nums[i + 1] == 0)
		{
			c++;
		}
		else if (nums[i] == 0 && nums[i + 1] != 0) {
			int temp = nums[i - c];
			nums[i - c] = nums[i + 1];
			nums[i + 1] = temp;
		}
	}

	return numsSize - count;
}

运行结果: 

思路二:设置一个计数器,从0到numsSize。如果nums[i]的值为val,则将当前的与最后一个交换,然后将最后一个元素删除;否则i++;最后返回numsSize。

int removeElement(int* nums, int numsSize, int val){
    
int i = 0;
while (i < numsSize)
{
	
	if (nums[i] == val)
	{
		nums[i] = nums[numsSize - 1];
		numsSize--;//数组大小-1
	}
	else
	{
		i++;
	}
}
return numsSize;
}

 运行结果:

总结:第二种算法只需要遍历一次就可以得出结果,而第一种需要遍历一次将其设置为0,在遍历第二次进行排序,从而第二种方法在时间上效率更高;而两种所用的空间都差不多,因此第二种算法更加简洁跟有效率。

 3.给你一个升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

思路:通过判断相同元素则往后排,通过第一次遍历将相同元素的设置为10001(题中提示最高数为10000),然后对其进行排序,从而是的重复的数往后排比较拖拉一点,因为循环多所以消耗的时间相对比较多。

int removeDuplicates(int* nums, int numsSize)
{
	int len = numsSize;
	int k = 0;
	int j = 0;
	for (k = 0; k < numsSize; k++)
	{
		for (j = k + 1; j < numsSize; j++)
		{
			if (nums[k] == nums[j])
			{
				nums[k] = 10001;
				len--;
			}
		}
	}
	int count = 0;
	for (int i = 0; i < numsSize - 1; i++)
	{
		if (nums[i] == 10001 && nums[i + 1] == 10001)
		{
			count++;
		}
		else if (nums[i] == 10001 && nums[i + 1] != 10001) {
			int temp = nums[i - count];
			nums[i - count] = nums[i + 1];
			nums[i + 1] = temp;
		}
	}
	
	return len;
}

运行结果:

 思路二:通过另一个变量指向第一个,然后判断往后的是否与其相等,如果相等就跳过,不等就将其放到j后面;

int removeDuplicates(int* nums, int numsSize) {
	int i, j = 0;
	for (i = 0; i < numsSize; i++)
	{
		if (nums[i] != nums[j])
		{
			j++;
			nums[j] = nums[i];
		}
	}
	if (numsSize > 0) return j + 1;
	return j;
}

 总结:第一种是排零的思路进行的,将重复的进行设置为阈值外,从而在经过一次排序就可以得到结果。第二种则是通过一次遍历,将重复的删除掉。从而第二种的效率会更高一点。

4.给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。

思路:通过len作为一个不动的元素,将i位置的元素给到len位置的元素,并往后移动一个,而判断条件则是如果有两个相同的,第三个不同,则进行一下赋值,不然len则不变。

int removeDuplicates(int* nums, int numsSize){
int len = 0;
	for (int i = 0; i < numsSize; i++)
	{
		if (len < 2 || nums[len - 2] != nums[i])
		{
			nums[len++] = nums[i];
		}
	}
	return len;
}

运行结果:

 以上都是LeetCode数组类算法的初始定义题目以及解法,个人能力有限,解法上还是很生涩,只供参考。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1033867.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号