アレイOJの質問

トピック1

(1)説明

numsの配列とvalの値が与えられた場合、値がvalと等しいすべての要素削除し、削除された配列の新しい長さを返す必要があります。

余分な配列スペースを使用しないでください。O(1)の余分なスペースのみを使用し、入力配列をその場で変更する必要があります。要素の順序は変更できます。新しい長さを超える配列内の要素を考慮する必要はありません。

(2)例

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

(3)考える

ダブルポインタ方式

  1. 最初にslowポインタslowを定義し、0-slow要素の値がvalではないことを規定します

ここに画像の説明を挿入
2.次に、fastポインターを使用して配列をトラバースし、fastが指すここに画像の説明を挿入
要素をvalと比較します。2つの状況があります。ポイントする要素の値がvalfastと等しいか等しくない
3.の値が指している要素はvalに等しい(上記のように)。o-slowは
ここに画像の説明を挿入
値がvalでない要素を格納することであると規定しているため高速ポインターは後方に移動し、「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;
}

ここに画像の説明を挿入

トピック2

(1)説明

並べ替えられた配列を指定したら、繰り返し要素削除して、各要素が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时会停止
    }
}

ここに画像の説明を挿入

トピック3

(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]。
ですから、1の場所から始めて、1つずつ追加していきます。1つ追加したら、配列に入れます。順番に並べられているので、最後に配列を逆にする必要があります。

まず、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));//找出这两个数组哪个大,新的数组最厉害也只能比它大一位

次のステップは、1から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