题目一
(1)描述
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
(2)示例
输入nums=[3,2,2,3],val=3
输出nums=[2,2],数组长度位2
(3)思路
采用双指针法
- 首先定义一个慢指针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;