トピック
範囲が1≤a[i]≤n(n =配列サイズ)の整数配列の場合、配列内の一部の要素は2回表示され、一部は1回だけ表示されます。
配列に表示されない範囲[1、n]のすべての数値を見つけます。
余分なスペースを使用せずにこのタスクを実行でき、時間計算量はO(n)ですか?返された配列は余分なスペースに含まれていないと想定できます。
例:
入力:
[4,3,2,7,8,2,3,1]
出力:
[5,6]
ソース:LeetCode
問題解決
テンプレート
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){
}
分析
質問の要件は、配列内の長さnの配列の場合、元の理由は配列内に1-nの自然数を保持することであるということです。含まれていない修飾された自然数がある場合、配列は次のように構成されます。そのタイプの自然数のが返されます。
論理分析
条件が利用可能で、要素はすべて1〜nの範囲内にあるため、元の配列の範囲に対応する新しい配列、添え字+1を作成できます。新しい配列は、で表されるnewに設定されます。 new [0]元の配列での1の出現回数です。
最後に返された新しい配列によると、0の場合は表示されず、対応する添え字+1は表示さ
れない数値です。これに基づいて、いくつかの論理的な変更が行われます。プロセス用の新しい配列を作成します。リソースの浪費を避けるために、ビルドしないでください。
参照コードは次のとおりです。[ポータル]
コード:
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {
for (int i = 0; i < numsSize; i++) {
int x = (nums[i] - 1) % numsSize;
nums[x] += numsSize;
}
int* ret = malloc(sizeof(int) * numsSize);
*returnSize = 0;
for (int i = 0; i < numsSize; i++) {
if (nums[i] <= numsSize) {
ret[(*returnSize)++] = i + 1;
}
}
return ret;
}