数组OJ题

题目一

(1)描述

给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

(2)示例

输入nums=[3,2,2,3],val=3
输出nums=[2,2],数组长度位2

(3)思路

采用双指针法

  1. 首先定义一个慢指针slow,并规定0-slow的元素的值都不是val

在这里插入图片描述
2. 接着使用fast指针遍历数组在这里插入图片描述
把fast所指向的元素与val进行比较,就会产生两种情况:所指元素值与val相等或者不相等fast
3. 如果所指元素值与val相等(如上图),由于我们规定o-slow是要存放值不为val的元素,所以fast指针后移,找寻下一个
在这里插入图片描述
此时来到“2”这个元素,发现其值不是val,那么就要将其放入0-slow区间中,也即此时要把fast所指元素赋值给slow
在这里插入图片描述
赋值完成后,slow指针就要向后移动一下在这里插入图片描述
4. 重复上述步骤

(4)代码实现

int removeElement(int* nums, int numsSize, int val)
{
    
    
    int slow=0;
    int fast=0;
    for(fast=0;fast<numsSize;fast++)
    {
    
    
        if(nums[fast]!=val)
        {
    
    
            nums[slow]=nums[fast];
            slow++;
        }
    }
    return slow;
}

在这里插入图片描述

题目二

(1)描述

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

(2)实例

输入nums=[1,1,1,2,2,2,3]
输出nums=[1,2,3]
返回数组长度为3

(3)思路

此题和第一题有点相似,具体思路看下图
在这里插入图片描述

在这里插入图片描述

(4)代码

int removeDuplicates(int* nums, int numsSize)
{
    
    
    int front=0;
    int behind=0;
    if(numsSize==0)//特别注意空数组的情况,往往就是这一个测试用例无法通过
    {
    
    
        return 0;
    }
    else
    {
    
    
        for(behind=1;behind<numsSize;behind++)
        {
    
    
            if(nums[front]!=nums[behind])
            {
    
    
                front++;
                nums[front]=nums[behind];
            }
        }
        return front+1;
        //注意这里要返回front+1,因为测试在输出时在到front时会停止
    }
}

在这里插入图片描述

题目三

(1)描述

对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1,2,3,1]。

给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。

(2)示例

在这里插入图片描述

(3)思路

例如X=1200,其数组形式A=[1,2,0,0],若K为34,则X+K=1234,X+K的数组形式=[1,2,3,4]。
所以从个位开始逐个相加,相加完一个,放在数组中,由于是顺序放的,所以最后还要逆置数组

首先我们要求出数字K有几位,以确定需要多大的数组

int* addToArrayForm(int* A,int ASize,int K,int* returnSize)
{
    
    
	int KSize=0;
	int KNum=k;
	while(KNum)
	{
    
    
		++KSize;
		KNum/=10;
	}
}
int len=ASize>KSize?ASize:KSize;
int* retarr=(int*)malloc(sizeof(int)*(len+1));//找出这两个数组哪个大,新的数组最厉害也只能比它大一位

接着就是要从个位开始逐个相加,相加时会涉及到进位的问题

int Ai=ASize-1;//找到数组A的最后一位
int reti=0;//reti用于控制相加后的下标
int nexnum=0;//用于控制进位
while(len--)//比如说最大长度为4为,那么他就要进行4次运算
{
    
    
	int a=0;
	if(Ai>=0)//如果是1200+34那都没有问题,因为Ai不会越界,但是如果是34+1200,Ai就会成为负数,所以此时对于34,如果Ai被检测为负数,说明到达了百位,那么它的百位和千位就都是0了.如果Ai是正数,那么就把正常的值赋值给a
	{
    
    
		a=A[Ai];
		Ai--;
	}
	int ret=a+K%10+nextnum;
	K/=10;//比如K=1234,%10,取出个位4,%10相当于取前三位进入下次循环,再取此时的个位3,以此类推
	if(ret>9)
	{
    
    
		ret-=10;//比如个位是9+9=18,那么个位的数字就是18-10=8;
		nexnum=1;//置为1,下一位就会进1
	}
	else
	{
    
    
		nexnum=0;
	}
	retarr[reti]=ret;
	++reti;//一次循环后,计算得到数字依次放到数组中
}
if(nexnum==1)
{
    
    
	retarr[reti]=1;
	++reti;//比如800+200=1000,相加时,计算到8+2的时候,已经算了三次,所以不会再进入循环,但是这一位没有进上去,所以对于这种情况要单独处理
}

最后,由于相加时放元素是从0,也就是按照顺序放置的,所以最后的结果和实际结果是相反的,所以要进行逆置

int left=0,right=reti-1;
while(left<right)
{
    
    
	 int temp=retarr[left];
	 retarr[left]=retarr[right];
	 retarr[right]=temp;
}

还有,返回值就是数组,一定注意形参的这个int* returnSize,它的意思就是要里面解引用修改数组的长度,不然外面是无法输出这个数组的,因为没有长度

	*returnSize=reti;
	return retarr;

猜你喜欢

转载自blog.csdn.net/qq_39183034/article/details/112582235
今日推荐