C++で配列内の最小値・2番目・3番目に小さい要素を効率的に見つける方法
n個の要素からなる配列が与えられたとき、その中から「1番目(最小)」「2番目」「3番目」に小さい要素を求めることを考えます。ここで、1番目の最小値は配列全体の最小値、2番目の最小値は1番目より大きい値の中で最も小さいもの、3番目の最小値は2番目より大きい値の中で最も小さいものを指します。
この問題は、配列を一度だけ走査しながら、各要素について「1番目・2番目・3番目の最小値」の条件を順に判定していくことで解くことができます。
アルゴリズムの考え方
まず、1番目・2番目・3番目の最小値を表す変数 first、sec、third を用意し、それぞれ int 型の最大値 INT_MAX で初期化します。次に、配列の各要素 arr[i] に対して以下の判定を行います。
- arr[i] が first より小さい場合:third に sec の値を、sec に first の値を移し、first を arr[i] で更新します。
- arr[i] が sec より小さい場合:third に sec の値を移し、sec を arr[i] で更新します。
- arr[i] が third より小さい場合:third を arr[i] で更新します。
この処理により、配列を1回走査するだけで3つの最小値を同時に求められます。時間計算量は O(n)、空間計算量は O(1) と非常に効率的です。
サンプルコード
#include<iostream>
using namespace std;
int getThreeMins(int arr[], int n) {
int first = INT_MAX, sec = INT_MAX, third = INT_MAX;
for (int i = 0; i < n; i++) {
if (arr[i] < first) {
third = sec;
sec = first;
first = arr[i];
} else if (arr[i] < sec) {
third = sec;
sec = arr[i];
} else if (arr[i] < third)
third = arr[i];
}
cout << "First min = " << first << endl;
cout << "Second min = " << sec << endl;
cout << "Third min = " << third << endl;
}
int main() {
int array[] = {4, 9, 18, 32, 12};
int n = sizeof(array) / sizeof(array[0]);
getThreeMins(array, n);
}実行結果
First min = 4 Second min = 9 Third min = 12
動作の解説
この例では、配列 {4, 9, 18, 32, 12} を先頭から順に処理していきます。
- 4 は INT_MAX より小さいため、first = 4 となります。
- 9 は first(4) より大きいですが sec(INT_MAX) より小さいため、sec = 9 となります。
- 18、32 はいずれの条件にも当てはまりません。
- 12 は sec(9) より大きく third(INT_MAX) より小さいため、third = 12 となります。
最終的に、最小値は 4、2番目に小さい値は 9、3番目に小さい値は 12 として出力されます。
注意点
このアルゴリズムでは重複した値も別々の要素として扱われます。たとえば配列に {4, 4, 9} が含まれる場合、2番目の最小値は 4 になります。もし「異なる値」として扱いたい場合は、比較条件に等号を含めるなどの工夫が必要です。また、配列の要素数が3未満の場合、INT_MAX のまま残る値が出力されるため、実用時には要素数のチェックを追加することをおすすめします。
-
C++で配列内の最小値と2番目に小さい値を検索する方法
n個の要素からなる配列が与えられたとき、その中で最も小さい要素(最小値)と、2番目に小さい要素を見つける必要があります。ここでいう「2番目に小さい要素」とは、最小値より大きい値の中で最小のものを指します。この問題は、配列の各要素を先頭から順に走査しながら、現時点での最小値と2番目に小さい値を適切に更新していくことで解決できます。アルゴリズムの考え方まず、最小値(first)と2番目に小さい値(sec)を、それぞれ int 型の最大値 INT_MAX で初期化します。次に配列を一巡するループの中で、以下の条件に従って値を更新していきます。現在の要素が最小値より小さい場合:2番目に小さい値を元の最
-
C++で最初の配列に存在し、2番目の配列には存在しない要素を検索する方法
概要2つの配列AとBが与えられたとき、配列Aには存在するが配列Bには存在しない要素をすべて見つける方法を解説します。AとBをそれぞれ集合(セット)とみなすと、この操作は「差集合(Set Difference)」の計算に相当します。C++では、標準ライブラリの std::set_difference アルゴリズムを使うことで、この差集合を簡単かつ効率的に求めることができます。set_differenceを使う際のポイントstd::set_difference は <algorithm> ヘッダで定義されているアルゴリズムです。使用する際は、以下の点に注意しましょう。入力となる両方の範