C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で指定されたN個の整数のうちちょうど1つだけを含む最大区間を求める方法

問題概要

N個の相異なる整数からなる配列が与えられたとします。このとき、与えられたN個の整数のうちちょうど1つだけを含み、かつ 1 ≤ L ≤ R ≤ 105 を満たす区間 [L, R] の中から、最も多くの整数を含む(=最も長い)区間を見つける必要があります。

例として、配列が Arr = [5, 10, 200] の場合を考えてみましょう。このときの出力は 99990 となります。候補となる区間は [1, 9]、[6, 199]、[11, 100000] の3つで、それぞれ 5、10、200 をちょうど1つずつ含みます。この中で最後の区間 [11, 100000] には 99990 個の整数が含まれており、これが最大値になります。

アルゴリズムの考え方

発想はシンプルです。まず、区間に含めたい要素を1つ固定し、他の要素と重ならないように、その区間を左方向・右方向へどこまで伸ばせるかを調べます。

具体的な手順は以下の通りです。

  • 配列をあらかじめ昇順にソートしておきます。
  • 番兵(sentinel)として 0 と 100001 を配列の先頭と末尾に追加します。これにより、最小値や最大値を固定する場合などの境界ケースを特別な分岐なしに統一的に扱えます。
  • ソート後の各要素 vec[i] について、区間の左端は「直前の要素 + 1」(vec[i-1] + 1)、右端は「直後の要素 − 1」(vec[i+1] − 1)として決定します。
  • 各区間の長さ(Right − Left + 1)を計算し、その最大値を答えとして返します。

この方法により、すべての要素 i に対して、その要素を唯一含む区間の最大長を効率よく求めることができます。

C++での実装例

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int maximumSize(vector<int>& vec, int n) {
    vec.push_back(0);
    vec.push_back(100001);
    n += 2;
    sort(vec.begin(), vec.end());
    int max_value = 0;
    for (int i = 1; i < n - 1; i++) {
        int Left = vec[i - 1] + 1;
        int Right = vec[i + 1] - 1;
        int count = Right - Left + 1;
        max_value = max(max_value, count);
    }
    return max_value;
}
int main() {
    vector<int> v;
    v.push_back(200);
    v.push_back(10);
    v.push_back(5);
    int n = v.size();
    cout << "Maximum Size is: " << maximumSize(v, n);
}

実行結果

Maximum Size is: 99990

計算量

ソートに O(N log N)、各区間の長さの計算に O(N) かかるため、全体の時間計算量は O(N log N) です。メモリについても、番兵2つ分の追加だけで済むため、空間計算量は O(N) と非常に効率的です。

  1. C++で整数Nの約数の中から最大の「良い数」を見つける方法

    問題の概要 この問題では、ある整数 N が与えられ、その約数の中に含まれる最大の「良い数(good number)」を見つけることが求められます。 「良い数」とは? 「良い数」とは、どの桁の数字も、それより右側(下位の桁)にあるすべての数字の合計よりも大きい数のことです。 たとえば 732 は良い数です。「7 > 3 + 2」「3 > 2」という条件がすべて満たされているためです。 入出力例 入力 : N = 15 出力 : 15 解説: 15 の約数は 1, 3, 5, 15 の4つです。この中で最大の良い数は 15 となります。 解法のアプローチ この問題へのシンプルな解

  2. 二分木から最大のBST部分木を見つける方法 - C++実装解説

    問題の概要 この記事では、二分木(BT)が与えられたときに、その中に含まれる最大のBST(二分探索木)部分木を見つけるという問題を解説します。 二分木とは、データを格納するために用いられる特殊なデータ構造で、「各ノードが最大2つの子ノードを持つ」という条件を満たす木構造です。 二分探索木(BST)は、すべてのノードが次の性質を満たす木のことです。 左部分木のキー値は、親(ルート)ノードのキー値よりも小さい。 右部分木のキー値は、親(ルート)ノードのキー値以上である。 具体例で問題を確認してみましょう。 入力: 出力:3 説明: 木全体がBSTとして成立しています。 解法アプローチ1:各ノ