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

【C++】指定した要素を削除した後に最小値を見つける方法

この記事では、2つの配列 arr[] と del[] が与えられたときに、del[] に含まれる要素を arr[] から削除した後の最小値を見つける問題を解説します。

具体的には、arr[] の値のうち del[] にも存在するものを取り除き、削除後の配列における最小値を出力します。なお、重複した値については del[] に出現する回数分だけ削除され、それ以外は残る点に注意が必要です。

例で問題を確認しよう

入力:

arr[] = {2, 5, 6, 9, 1}
del[] = {1, 5, 9}

出力:

2

この例では、arr[] から 1・5・9 が削除されるため、残った値の中で最も小さい 2 が結果となります。

解決アプローチ:ハッシュを活用する

この問題に対するシンプルかつ効率的な解法がハッシュ(ハッシュマップ)を使う方法です。手順は以下の通りです。

  • まず、del[] 配列のすべての値をハッシュテーブルに挿入します(このとき各値の出現回数もカウントしておきます)。
  • 次に、arr[] を先頭から走査し、各値がハッシュテーブルに存在するかを確認します。
  • 存在する場合は削除対象なのでスキップし、ハッシュ内のカウントを1減らします。カウントが0になったらエントリを削除します。
  • 存在しない場合は候補となる値なので、現在の最小値(minVal)より小さければ更新します。
  • 最終的に得られた minVal が答えとなります。

この手法により、重複した値を含む場合でも、指定された回数だけ正確に要素を削除することが可能です。

実装例

上記の解法の動作を示すC++プログラムは以下の通りです。

#include <bits/stdc++.h>
using namespace std;
int findSmallestVal(int arr[], int m, int del[], int n){
    unordered_map<int, int> delVals;
    for (int i = 0; i < n; ++i) {
        delVals[del[i]]++;
    }
    int minVal = INT_MAX;
    for (int i = 0; i < m; ++i) {
        if (delVals.find(arr[i]) != delVals.end()) {
            delVals[arr[i]]--;
            if (delVals[arr[i]] == 0)
                 delVals.erase(arr[i]);
        }
        else
            minVal = min(minVal, arr[i]);
    }
    return minVal;
}
int main(){
    int array[] = { 5, 12, 33, 4, 56, 12, 20 };
    int m = sizeof(array) / sizeof(array[0]);
    int del[] = { 12, 4, 56, 5 };
    int n = sizeof(del) / sizeof(del[0]);
    cout<<"The smallest value after the deleting element is "<<findSmallestVal(array, m, del, n);
    return 0;
}

出力

The smallest value after the deleting element is 12

実行結果の解説

このサンプルコードでは、arr[] に 12 が2回登場しますが、del[] には 12 が1回しか含まれていないため、削除されるのは最初の1つだけです。したがって、削除後に残る最小値は 12 となります。このように、ハッシュで出現回数を管理することで、重複を含むケースでも正しく動作させることができます。

まとめ

本記事では、配列から指定要素を削除した後に最小値を求める問題について、ハッシュマップを利用した解法を紹介しました。時間計算量は O(m + n)(m は arr[] の要素数、n は del[] の要素数)となり、非常に効率的です。重複データの扱い方にも触れましたので、同様のアルゴリズム問題を解く際の参考にしてください。

  1. C++で指定された差分を持つペアを見つける方法

    はじめに 配列 A に n 個の異なる要素が格納されているとします。この配列から、2つの要素 x と y の差が指定された値 d と一致するようなペア (x, y) をすべて見つける必要があります。 例として、配列が A = [10, 15, 26, 30, 40, 70]、指定された差分が 30 である場合を考えます。このとき、該当するペアは (10, 40) と (40, 70) です。 解法:ツーポインタ法 この問題は、配列が昇順にソートされていることを前提とすれば、ツーポインタ(二重インデックス)法を使って効率的に解くことができます。まず、1つ目のポインタ「i」を先頭の要素に、2つ目の

  2. C++で配列要素の階乗の最大公約数(GCD)を求める方法

    N個の要素を持つ配列Aが与えられたとき、配列内のすべての要素の階乗の最大公約数(GCD)を求めることを考えます。例えば、配列の要素が {3, 4, 8, 6} の場合、各要素の階乗は 3! = 6、4! = 24、8! = 40320、6! = 720 となり、これらのGCDは 6 になります。解法のポイントここで重要な数学的な性質があります。2つの数のGCDとは、両方の数を割り切る最大の数のことです。階乗の場合、小さい数の階乗は必ず大きい数の階乗を割り切ることができます。つまり、2つの階乗のGCDは、小さい方の数の階乗そのものになります。例えば、3! と 5! のGCDを考えると、3! =