2017-12-22 3 views
1

これはコード26です。ソートされた配列では、各要素が一度しか現れず、新しい長さを返すようにインプレースで複製を削除します。例はnums = [1,1,2]と与えられ、関数は[1,2]を返さなければなりません。'value_type'型のヌルポインタへの参照への参照

以下は私のコードです。私は他のすべての重複を削除し、ちょうどそれらの1つを残します。しかし、私は常に、 "value_type '型のnullポインタへの参照バインディングのエラーが出てきました。誰かが私にこれを手伝ってもらえれば幸いです!

class Solution { 
public: 
    int removeDuplicates(vector<int>& nums) { 
     int i = 0; 
     while(i < nums.size() - 1) { 
      if (nums[i] == nums[i + 1]) { 
       nums.erase(nums.begin() + i); 
      } 
      else i++; 
     } 
     return nums.size(); 
    } 
}; 
+0

複製できません。 https://ideone.com/ppuRg5。 –

+0

エラーメッセージを表示する完全なプログラムを表示します。 –

答えて

2

vector<T>::size() unsigned型である、タイプsize_tの値を返します。渡されたベクトルが空で、ベクトルの長さが0であるとしましょう。nums.size() - 1は整数アンダーフローを引き起こし、実際には0と非常に大きな正の数を比較します。これは、ループが実行され、iが配列の境界を通過することを真に評価します。

これを修正するには、先にnums.size()intをキャストするか、サイズを整数変数に格納して比較してください。

+1

また、while(i + 1 Barmar

0

投稿された関数は、要素が[1 1 2]のベクトルに対してうまく機能します。 https://ideone.com/ppuRg5を参照してください。

しかし、私があなたの関数で見る問題の1つは、空のベクトルを渡すと問題に遭遇するということです。

while(i < nums.size() - 1) 

は、numsが空の場合に問題になります。空のベクトルであることがわかったらすぐにその関数から戻って、先にその問題を回避することができます。

また、iには符号なしの型を使用して、符号付きの型と符号なしの型の比較に関するコンパイラの警告を回避します。

int removeDuplicates(std::vector<int>& nums) { 
    if (nums.empty()) 
    { 
     return 0; 
    } 

    unsigned int i = 0; 
    while(i < nums.size() - 1) { 
     if (nums[i] == nums[i + 1]) { 
     nums.erase(nums.begin() + i); 
     } 
     else i++; 
    } 
    return nums.size(); 
} 
0

これは、あなたの質問への答えではありませんが、あなたはベクトルあなたが重複を見つけるたびにサイズを変更する必要はありませんでした場合、それは問題に、より効率的な解決策になります。あなたにアイデアを与えるだけで、2つのイテレーターiとjを持つことができます。私はあなたの解ベクトルの最後のユニークな要素のインデックスを保持し、ベクトルを反復します。 jが最初のi要素にない値を指している場合は、それをv [i]にコピーします。そして、あなたが終わったら、j番目からすべてを削除してください。