C++で隣接要素間の差が0または1となる最大長の部分配列を求める方法
任意のサイズの整数型配列が与えられたとき、「隣接する要素間の差が0または1」という条件を満たす最大長の部分配列(サブ配列)を見つけることが本記事の課題です。
問題例
入力 − int arr[] = { 2, 1, 5, 6, 3, 4, 7, 6 }
出力 − 隣接要素間の差が0または1となる最大長の部分配列の長さ − 2
説明 − 差が0または1となる隣接要素の組は {2, 1}、{5, 6}、{3, 4}、{7, 6} の4つです。いずれも長さが2であるため、最大長の部分配列の長さは2となります。
入力 − int arr[] = { 2, 1, 7, 6, 5 }
出力 − 隣接要素間の差が0または1となる最大長の部分配列の長さ − 3
説明 − 差が0または1となる隣接要素の組は {2, 1} と {7, 6, 5} です。このうち {7, 6, 5} が最も長いため、最大長の部分配列の長さは3となります。
プログラムで使用するアプローチ
- 正の要素と負の要素の両方を含みうる整数型の配列を入力として受け取ります。
- 配列のサイズを計算し、配列とサイズを関数に渡して以降の処理を行います。
- 一時変数 i を0に初期化し、最大長を格納する変数 maximum も0に初期化します。
- i が配列のサイズに達するまで while ループを実行します。
- ループの先頭で j を i に設定し、走査開始位置を記録します。
- 内側のループで、隣接する要素間の差が0または1であるかどうかを abs() 関数で判定しながら部分配列を伸ばしていきます。
- 条件を満たす限り i の値をインクリメントします。
- temp に現在の部分配列の長さ i - j + 1 を設定します。
- maximum が temp より小さい場合は、maximum を temp で更新します。
- j が i と等しい場合(隣接要素の条件を一度も満たさなかった場合)は、i をインクリメントして次の要素へ進みます。
- maximum を返します。
- 結果を出力します。
このアルゴリズムは配列を一度だけ走査するため、計算量は O(n)、追加のメモリ使用量は O(1) であり、非常に効率的です。
サンプルコード
#include<bits/stdc++.h>
using namespace std;
// 隣接要素間の差が0または1となる
// 最大長の部分配列を計算する関数
int maximum_diff(int arr[], int size){
int i = 0;
int maximum = 0;
while (i < size){
int j = i;
while (i+1 < size && (abs(arr[i] - arr[i + 1]) == 1 || abs(arr[i] - arr[i + 1]) == 0)){
i++;
}
int temp = i - j + 1;
if (maximum < temp){
maximum = temp;
}
if(j == i){
i++;
}
}
return maximum;
}
int main(){
int arr[] = { 2, 1, 5, 6, 3, 4, 7, 6};
int size = sizeof(arr) / sizeof(arr[0]);
cout<<"隣接要素間の差が0または1となる最大長の部分配列の長さ: "<< maximum_diff(arr, size);
}出力結果
隣接要素間の差が0または1となる最大長の部分配列の長さ: 2
-
C++で行列の任意の列から最大の差を持つペアを検索する方法
N×N の行列が与えられたとき、行列の任意の列から要素のペアを取り出し、その差が最大になるペアを見つける問題を考えてみましょう。例えば、次のような行列があるとします。123535967この場合、出力は 8 になります。最大の差を持つペアは 0 列目の (1, 9) だからです。解法のアイデア考え方は非常にシンプルです。各列ごとに最大値と最小値を求め、その差を計算します。そして、すべての列の中で最も大きな差を返せばよいのです。アルゴリズムの手順各列について、最初の行の値を最大値・最小値の初期値として設定します。残りの行を順に走査しながら、最大値と最小値を更新していきます。その列の最大値と最小値の
-
C++で要素の積とLCMが一致する最長部分配列を求めるアルゴリズム
問題概要配列 A が与えられたとき、「その部分配列の最小公倍数(LCM)」と「部分配列内の要素の積」が一致するような部分配列の中で、最も長いものの長さを求めます。条件を満たす部分配列が存在しない場合は -1 を返します。例として、配列が {6, 10, 21} である場合を考えてみましょう。部分配列 {10, 21} に注目すると、その最小公倍数は 210、要素の積も 210 となり、両者が一致します。このため、答えは 2 となります。解き方のアプローチこの問題へのアプローチは非常にシンプルです。長さ 2 以上のすべての部分配列を網羅的にチェックし、条件を満たすものが見つかるたびに、これまでの