C++で配列の中央値を最大化する方法を解説
問題の概要
N個の要素を含む配列 arr[] と整数 K(K < N)が与えられます。求められているのは、この配列にK個の整数要素を挿入し、結果として得られる配列の中央値を最大化することです。
例として、入力配列が {1, 3, 2, 5}、k = 3 の場合を考えてみましょう。
- 配列をソートすると {1, 2, 3, 5} になります
- 最大値の5より大きい要素を3つ挿入します。この操作により、配列は {1, 2, 3, 5, 6, 6, 6} になります
- 新しい配列の中央値は 5 となります
アルゴリズムの考え方
この問題を解くためのポイントは、以下の2点です。
- 挿入する要素の選び方: 中央値を最大化するには、挿入するすべての要素が元の配列の最大要素より大きくなければなりません。こうすることで、挿入された要素はすべて中央値の位置より後ろに並ぶため、元の配列の中央部分がそのまま保たれます。
- 中央値の求め方: 配列をソートした後、新しいサイズが奇数の場合は中央値は arr[size / 2]、偶数の場合は (arr[(size / 2) - 1] + arr[size / 2]) / 2 として計算できます。
C++による実装例
#include <bits/stdc++.h>
using namespace std;
double getMaxMedian(int *arr, int n, int k){
int newSize = n + k;
double median;
sort(arr, arr + n);
if (newSize % 2 == 0) {
median = (arr[(newSize / 2) - 1] + arr[newSize / 2]) / 2;
return median;
}
median = arr[newSize / 2];
return median;
}
int main(){
int arr[] = {1, 3, 2, 5};
int n = sizeof(arr) / sizeof(arr[0]);
int k = 3;
cout << "Max median = " << getMaxMedian(arr, n, k) << endl;
return 0;
}実行結果
上記のプログラムをコンパイルして実行すると、以下の出力が得られます。
Max median = 5
計算量の分析
このアルゴリズムの時間計算量は、配列のソートが支配的となるため O((N + K) log(N + K)) です。また、追加のメモリを必要としないため、空間計算量は O(1) となります。
まとめ
配列の中央値を最大化するには、最大値より大きい要素を挿入するだけでよく、複雑なデータ構造は一切不要です。ソート後に中央位置の要素を取り出すだけで答えが得られる、シンプルでありながら考え方が重要な問題といえます。
-
C ++で配列のプレフィックスに-1を掛けて、配列の合計を最大化します。
整数配列が与えられ、タスクは最初に配列のプレフィックスをフェッチし、次にそれを-1で乗算し、次にアレイのプレフィックス合計を計算し、最後に生成されたプレフィックス配列から最大合計を見つけることです。 プレフィックス配列は-として生成されます prefixArray[0]の最初の要素=配列の最初の要素 prefixArray[1]の2番目の要素=prefixArray[0] + arr [1] prefixArray[2]の3番目の要素=prefixArray[1] + arr [2] prefixArray[3]の4番目の要素=prefixArray[2] +arr[3]…..et
-
C++で解く迷路問題:転がるボールが目的地に止まれるかをBFSで判定する方法
迷路の中にボールがあるとします。迷路には空きスペース(通路)と壁があります。ボールは上下左右のいずれかの方向に転がって空き通路を進むことができますが、壁にぶつかるまで止まりません。ボールが停止したときに、次の方向を選べます。この問題では、ボールの開始位置、目的地、そして迷路そのものが与えられ、「ボールが目的地の位置で停止できるかどうか」を判定する必要があります。迷路は2次元配列で表現され、1は壁、0は空きスペースを意味します。迷路の外周はすべて壁になっています。開始位置と目的地は行・列のインデックス(座標)で与えられます。問題例たとえば、次のような2次元配列で表される迷路を考えてみましょう。0