C++で正方行列の最大値と最小値を効率的に求める方法
問題文
n×n の正方行列が与えられたとき、その行列に含まれる要素の中から最大値と最小値を求めるプログラムを作成します。
例
例として、次のような 3×3 の行列が与えられたとします。
{{15, 17, 19}, {5, 1, 7}, {14, 5, 16}}この場合、最小値は 1、最大値は 19 となります。
アルゴリズム
- 行列の各行について、行の先頭の要素と行の末尾の要素のように、対になる2つの要素を選びます。
- 選んだ2つの要素を比較し、小さい方を現在の最小値と、大きい方を現在の最大値と照らし合わせます。必要に応じて最小値・最大値を更新します。
- 2つの要素を処理するのに必要な比較は3回なので、行列全体を走査するのに必要な比較回数は合計で 3/2 × n² 回になります。これは全要素を1つずつ単純に比較する方法(2n² 回)と比べて効率的です。
C++での実装例
それでは、実際のコードを見てみましょう。
#include <bits/stdc++.h>
#define MAX 200
using namespace std;
void getMinMax(int matrix[MAX][MAX], int n) {
int min = INT_MAX;
int max = INT_MIN;
for (int i = 0; i < n; ++i) {
for (int j = 0; j <= n / 2; ++j) {
if (matrix[i][j] > matrix[i][n - j - 1]) {
if (min > matrix[i][n - j - 1]) {
min = matrix[i][n - j - 1];
}
if (max < matrix[i][j]) {
max = matrix[i][j];
}
} else {
if (min > matrix[i][j]) {
min = matrix[i][j];
}
if (max < matrix[i][n - j - 1]) {
max = matrix[i][n - j - 1];
}
}
}
}
cout << "Maximum = " << max << ", Minimum = " << min << endl;
}
int main() {
int matrix[MAX][MAX] = { {15, 17, 19}, {5, 1, 7}, {14, 5, 16} };
getMinMax(matrix, 3);
return 0;
}出力
Maximum = 19, Minimum = 1
まとめ
このアルゴリズムでは、行の両端から要素をペアで比較していくことで、比較回数を 3/2 × n² 回に抑えられます。行列のサイズが大きくなるほど、全要素を個別に比較する素朴な手法と比べて処理効率の向上が期待できます。
-
【C++】連結リスト内で指定した数Kで割り切れる最大要素と最小要素を求める方法
連結リストとは 連結リスト(リンクリスト)は、要素同士がポインタで連結された線形データ構造です。各要素(ノード)は「データ部分」と「次の要素を指すリンク(ポインタ)」を持ち、メモリ上の連続していない場所に配置されることもあります。 本記事では、データ部分と次ノードへのリンクを持つ片方向連結リストと、整数Kが与えられます。目的は、連結リスト内の要素のうち「Kで割り切れる」要素の最大値と最小値を見つけることです。線形連結リストは一方向にしか走査できないため、ヘッド(先頭)ノードから順に各ノードを訪問し、そのデータ部分がKで割り切れるかどうかを判定します。現在のノードの値が、それまでに見つかった最
-
C++で連結リスト内の最小値・最大値の素数を求める方法
問題文n個の正の整数からなる連結リストが与えられます。このリストの中から、値が最小の素数と最大の素数を見つける必要があります。例えば、次のようなリストが与えられた場合 −10 -> 4 -> 1 -> 12 -> 13 -> 7 -> 6 -> 2 -> 27 -> 33この場合、最小の素数は 2、最大の素数は 13 となりますアルゴリズム1. 与えられた数の中から最大値を求める(これを maxNumber と呼ぶ)2. 1 から maxNumber までの素数を生成し、動的配列に格納する3. 連結リストを走査し、動的配列を参照して最小値・