説明#
配列 nums と値 val が与えられた場合、インプレースで値が val と等しい要素をすべて削除し、削除後の配列の新しい長さを返します。
余分な配列空間を使用しないで、入力配列をインプレースで変更し、O (1) の追加スペースを使用して処理を完了する必要があります。
要素の順序は変更できます。新しい長さの後に配列内の要素を考慮する必要はありません。
例 1:
nums = [3,2,2,3]、val = 3 の場合、
関数は新しい長さ 2 を返し、nums の最初の 2 つの要素はいずれも 2 です。
新しい長さの後に配列内の要素を考慮する必要はありません。
例 2:
nums = [0,1,2,2,3,0,4,2]、val = 2 の場合、
関数は新しい長さ 5 を返し、nums の最初の 5 つの要素は 0、1、3、0、4 です。
これらの 5 つの要素は任意の順序であることに注意してください。
新しい長さの後に配列内の要素を考慮する必要はありません。
注意:
なぜ返される値が整数であり、出力の答えが配列なのでしょうか?
入力配列は **「参照」** の形式で渡されることに注意してください。つまり、関数内で入力配列を変更すると、呼び出し元にもその変更が反映されます。
次のような内部操作を想像することができます:
// nums は「参照」の形式で渡されます。つまり、実引数にはコピーが作成されません
int len = removeElement(nums, val);
// 関数内で入力配列を変更すると、呼び出し元にもその変更が反映されます。
// 関数の返り値の長さに基づいて、その長さの範囲内の配列のすべての要素が印刷されます。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
アプローチ#
- 以前の重複した要素を削除するコードと似ていますが、重複を判定する条件を固定値に変更し、検索も最初から行う必要があるため、以前のコードを少し変更します
void exchange(int* num1,int* num2) {
*num1 ^= *num2;
*num2 ^= *num1;
*num1 ^= *num2;
}
int removeElement(int* nums, int numsSize, int val){
for(int now = 0,last_find = 0;;now++) {//現在の位置
for(int find = last_find;;find++) {//検索ポインタ
if(find >= numsSize)//検索終了
return now;
if(nums[find] != val) {//指定の要素が見つかった
if(find != now)
exchange(nums+now,nums+find);
last_find = find + 1;//次回の検索は次の要素から開始
break;
}
}
}
}