問題:
並べ替えられた配列が与えられた場合、繰り返されている要素を削除して、各要素が一度だけ表示されるようにし、削除後に配列の長さを返す必要があります。
余分な配列スペースを使用しないでください。入力配列を適切に変更し、O(1)余分なスペースを使用して変更する必要があります。
例1:
配列nums = [1,1,2]の場合、
関数は新しい長さ2を返し、元の配列numsの最初の2つの要素は1、2に変更されます。
新しい長さを超えて配列の要素を考慮する必要はありません。
例2:
nums = [0,0,1,1,1,2,2,3,3,4]の場合、
関数は新しい長さ5を返し、元の配列nums の最初の5つの要素が0、1に変更されます。 2、3、4。
新しい長さを超えて配列の要素を考慮する必要はありません。
説明:
戻り値が整数であるのに、出力への答えが配列である
理由?入力配列は「参照」によって渡されることに注意してください。これは、関数の入力配列の変更が呼び出し元から見えることを意味します。
次のような内部操作を想像できます。
// numsは「参照」によって渡されます。言い換えると、実際のパラメーターのコピーを作成しないでください
int len = removeDuplicates(nums);
//関数の入力配列を変更すると、呼び出し元に表示されます。
//関数によって返された長さに基づいて、配列の長さの範囲内のすべての要素を出力します。
for(int i = 0; i <len; i ++){
print(nums [i]);
}
問題解決のアイデア:
配列の反復について考えました。添え字インデックスを使用してマークを付けてから、配列を走査して、現在の数とマークされた添え字の数が等しいかどうかを判断します。
しかし、それは解決されず、次に消去メソッドが使用されました。コードは次のとおりです。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int index=0;
for(auto it=nums.begin()+1;it<nums.end();it++,index++){
if(*it == nums[index]){
nums.erase(it);
it--;
index--;
}
}
return nums.size();
}
};
その後、消去方法を使うのは時間がかかりすぎると感じたので、探索と代入の方法について考え続けました。解決後、時間の消費が大幅に削減されます。ACコードは次のとおりです。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(0 == nums.size()) return 0; //注意长度为0的情况
int index=0;
for(int i=1;i<nums.size();i++){
if(nums[i] != nums[index]){
index++;
nums[index] = nums[i];
}
}
return index+1;
}
};