C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でソート済み配列から重複を削除する方法(各要素は最大2回まで許容)

ソートされた配列 nums が与えられたとき、同じ要素が最大2回まで現れるように、配列自体を書き換える形(インプレース)で重複を削除し、新しい長さを返すことを考えます。

この問題の重要な制約は、追加のメモリを使用できないという点です。つまり、O(1)の追加領域だけで解決しなければなりません。

例えば、入力配列が [0,0,0,1,1,1,1,2,3,3] の場合、出力は [0,0,1,1,2,3,3] となり、新しい長さは 7 になります。

アルゴリズムの考え方

この問題は「二ポインタ(書き込み位置と読み取り位置)」を使うテクニックで効率的に解けます。ポイントは、既に確定した末尾2つの要素と比較することで、「3連続以上の重複」を防ぐことです。

手順

  • 書き込み位置 len を 2 に初期化し、配列サイズを n とします。
  • n <= 2 の場合は、どの要素も削除不要なのでそのまま n を返します。
  • i = 2 から n - 1 までループします。
    • nums[i]nums[len - 2] または nums[len - 1] のいずれかと異なる場合(= まだ2連続になっていない場合)、nums[len] = nums[i] としてコピーし、len を1増やします。
  • 最後に len を返します。

この方法なら、各要素は時間計算量 O(n)、追加空間 O(1) で処理できます。

C++での実装例

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   int removeDuplicates(vector<int>& nums) {
      int len = 2;
      int n = nums.size();
      if(n <= 2)return n;
      for(int i = 2; i < n; i++){
         if( nums[i] != nums[len - 2] || nums[i] != nums[len - 1]){
            nums[len] = nums[i];
            len++;
         }
      }
      return len;
   }
};
main(){
   Solution ob;
   vector<int> v = {0,0,0,1,1,1,1,2,3,3};
   cout << ob.removeDuplicates(v);
}

入力

[0,0,0,1,1,1,1,2,3,3]

出力

7

まとめ

このアルゴリズムでは、配列の先頭2要素は必ず残るため len を 2 から開始し、3番目以降の要素について「直前に確定した2要素との比較」を行うことで、同一要素が3回以上連続して現れるのを防いでいます。条件式で OR(||)を使っているため、直前2つのうちどちらか一方でも異なればその要素を採用でき、正しく「最大2回まで」というルールを実現できます。

  1. JavaでArrayListから重複要素を削除する方法を解説

    本記事では、JavaのArrayList(配列リスト)から重複する要素を削除する方法について詳しく解説します。 リスト(List)とは、要素を順序付けて格納し、順番にアクセスできるコレクションのことです。インデックスベースのメソッドを使って、要素の挿入・更新・削除・検索を行うことができます。ただし、リストは重複した要素を持つことが許されているため、場合によっては重複を取り除く処理が必要になります。 処理内容のデモンストレーション 以下に、実際の動作例を示します。 入力: 定義されたリスト: [Java, Scala, Python, Java] 期待される出力: 重複削除後のリスト: [Jav

  2. Pythonでソート済み配列から重複要素を削除する方法

    ここでは、ソート済みのリストから重複する要素をすべて削除し、その後の配列の長さ(ユニークな要素の個数)を返す問題を扱います。重要な制約として、O(1)の追加メモリで実行する必要があります。つまり、新しい配列を作成せずに、元の配列をインプレース(in-place)で操作しなければなりません。問題の例例えば、次のような入力が与えられたとします。A = [1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6]この場合、重複を除いたユニークな要素は「1, 2, 3, 4, 5, 6」の6つなので、出力は 6 となります。解法のアプローチこの問題は、以下の手順で解くことができ