C++で配列内の最大連続数を求める方法を解説
正の整数からなる配列が与えられたとき、その中に存在する「連続した整数」(値が1ずつ増えていく並び)の最大個数を求めることを考えます。
基本的な考え方は次のとおりです。まず配列を昇順にソートし、隣接する要素同士を比較します。arr[j]==arr[i]+1(j=i+1)が成り立てば連続していると判断できるため、カウントを1増やしてインデックスを進めます(i++、j++)。差が1でなければcountを1にリセットします。そして、それまでに見つかった最大のカウントをmaxcに記録していきます。
入力例1
Arr[]= { 100,21,24,73,22,23 }
出力例1
Maximum consecutive numbers in array : 4
解説: ソート後の配列は { 21,22,23,24,73,100 } となります。初期値は count=1、maxcount=1 です。
1. 22=21+1 → count=2, maxcount=2, i++, j++ 2. 23=22+1 → count=3, maxcount=3, i++, j++ 3. 24=23+1 → count=4, maxcount=4, i++, j++ 4. 73≠24+1 → count=1, maxcount=4, i++, j++ 5. 100≠73+1 → count=1, maxcount=4, i++, j++
したがって、最大連続数は4({ 21,22,23,24 })です。
入力例2
Arr[]= { 11,41,21,42,61,43,9,44 }
出力例2
Maximum consecutive numbers in array : 4
解説: ソート後の配列は { 9,11,21,41,42,43,44,61 } となります。初期値は count=1、maxcount=1 です。
1. 11≠9+1 → count=1, maxcount=1, i++, j++ 2. 21≠11+1 → count=1, maxcount=1, i++, j++ 3. 41≠21+1 → count=1, maxcount=1, i++, j++ 4. 42=41+1 → count=2, maxcount=2, i++, j++ 5. 43=42+1 → count=3, maxcount=3, i++, j++ 6. 44=43+1 → count=4, maxcount=4, i++, j++ 7. 61≠44+1 → count=1, maxcount=4, i++, j++
したがって、最大連続数は4({ 41,42,43,44 })です。
プログラムのアプローチ
整数型配列 Arr[] に整数を格納します。
整数 n には配列の長さを格納します。
関数 subs(int arr[], int n) は、配列とそのサイズを引数として受け取り、配列内に存在する最大連続数を返します。
まず sort(arr,arr+n) を使って配列をソートします。
次に count=1、maxc=1 として初期化します。
最初の2要素 arr[0] と arr[1] から始めて、二重のforループ内で arr[j]==arr[i]+1(j=i+1)が成り立つかを比較し、真であれば count と i を1ずつ増やします。
上記の条件が偽の場合は count を1に戻します。maxc は常に見つかった最大のカウントで更新します(maxc = count > maxc ? count : maxc)。
最後に maxc を最大連続要素数として結果として返します。
サンプルコード
#include <iostream>
#include <algorithm>
using namespace std;
int subs(int arr[],int n){
std::sort(arr,arr+n);
int count=1;
int maxc=1;
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if(arr[j]==arr[i]+1){
count++;
i++;
}
else
count=1;
maxc=count>maxc?count:maxc;
}
}
return maxc;
}
int main(){
int arr[] = { 10,9,8,7,3,2,1,4,5,6 };
int n = sizeof(arr) / sizeof(int);
cout << "Maximum consecutive numbers present in an array :"<<subs(arr, n);
return 0;
}
出力
Maximum consecutive numbers present in an array : 10
この例では、配列をソートすると { 1,2,3,4,5,6,7,8,9,10 } となり、すべての要素が連続しているため、最大連続数は10となります。
-
C++で配列内に存在するキーKの出現確率を求める方法
問題概要サイズ「n」の配列が与えられ、その配列内に指定された要素 k が存在する場合に、その出現確率を求めることが課題です。配列の要素数と等しい「n」まで配列全体を走査し、指定された要素(キー)「k」を検索します。要素が配列内に存在する場合はその確率を計算して返し、存在しない場合は 0 を出力します。入力arr[] = { 1, 2, 3, 4, 5, 6} K = 5出力配列におけるキー 5 の確率 : 0.166入力arr[] = { 1,2,3,4,5,6,7 } K = 8出力配列におけるキー 8 の確率 : 0考え方上記はサイズ 7 の配列とキー 2 を例とした説明です。この場合、配
-
C++で配列を最大K個に分割して平均の合計を最大化する方法
問題概要 数値の配列 A が与えられます。この配列を最大 K 個の隣接する(空でない)グループに分割し、スコアを「各グループの平均値の合計」と定義します。このとき、達成できる最大スコアを求めるのが本問題です。 入力例 入力配列が {9, 2, 5, 3, 10} の場合、たとえば次のように分割できます。 {9} {2, 5, 3} {10} このときの平均の合計は次のとおりです。 9 + (2 + 5 + 3) / 3 + 10 = 22.33 アルゴリズム(メモ化再帰) この問題は、メモ化(記憶化)再帰を使うことで効率よく解くことができます。 memo[i][k]:A[i]〜A[n-1]