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

C++で区間の集合の中に重なり合う区間が存在するかどうかを判定する方法

あるイベントの開始時刻と終了時刻を表す値のペア(time1, time2)から構成される区間の集合が与えられたとします。ここでの課題は、この集合の中に他の区間と重なり合っている区間が存在するかどうかを確認することです。重なりが1つでも見つかれば True を返し、まったく重なりがなければ False を返します。

例えば、入力が [(4,7), (5,11), (7,11), (5,8)] のような場合、出力は True になります。これは複数の区間が互いに重なっているためです。

解決のアプローチ

この問題は、以下の手順で効率的に解決できます。

  • まず、入力リスト inputArr を開始時刻(time1)を基準にソートします。
  • インデックス 1 から inputArr のサイズまでループ処理を行います。
    • もし inputArr[i - 1].time2 > inputArr[i].time1 が成り立つ場合、前の区間の終了時刻が次の区間の開始時刻より後であることを意味するため、
      • True を返します。
    • ループが完了しても重なりが見つからなければ、False を返します。

ソート後は隣接する区間同士だけを比較すればよいため、全体の計算量は O(n log n)(ソート部分が支配的)となり、非常に効率的です。

実装例

それでは、実際のC++コードを見て理解を深めましょう。

#include <bits/stdc++.h>
using namespace std;
class IntervalClass {
public:
    int time1, time2;
};
bool compare(IntervalClass inst1, IntervalClass inst2){
    return (inst1.time1 < inst2.time1) ? true : false;
}
bool solve(vector<IntervalClass> &inputArr){
    int size = inputArr.size();
    sort(inputArr.begin(), inputArr.end(), compare);
    for (int i = 1; i < size; i++)
        if (inputArr[i - 1].time2 > inputArr[i].time1)
            return true;
    return false;
}
int main(){
    vector<IntervalClass> inputArr = {{4,7},{5,11},{7,11},{5,8}};
    cout << solve(inputArr);
}

入力

{{4,7},{5,11},{7,11},{5,8}}

出力

1

コードの解説

このコードでは、IntervalClass クラスで各区間の開始時刻(time1)と終了時刻(time2)を保持しています。compare 関数は、区間を開始時刻順に並べるための比較関数です。

solve 関数では、まず sort によって全ての区間を開始時刻順に並べ替えます。その後、隣接する区間を順番に比較し、「前の区間の終了時刻が次の区間の開始時刻を超えている」場合は重なりがあると判断して true を返します。

上記の例では、例えば (4,7) と (5,11) のように、ソート後に隣接する区間が重なっているため、出力は 1(True)となります。もし全ての区間が互いに離れていれば、出力は 0(False)になります。

  1. C++で特定の二分木がヒープかどうかを判定する方法

    概念与えられた二分木に対して、それがヒープの性質(ヒープ属性)を持っているかどうかを検証する必要があります。二分木がヒープであるためには、次の2つの条件を満たしていなければなりません。二分木が完全木であること(最後のレベルを除くすべてのレベルが埋まっている状態)。二分木のすべてのノードの値が、その子ノードの値以上であること(最大ヒープ(max-heap)を想定した場合)。例以下の例では、この木はヒープの性質を満たしています。一方、次の例はヒープの性質を満たしていません。アプローチ上記の2つの条件は、それぞれ別々に検証する必要があります。完全性の検証には isComplete(二分木が完全木かど

  2. C++で二分木がSumTree(総和木)かどうかを判定する方法

    ここでは、与えられた二分木が「SumTree(総和木)」であるかどうかを判定する方法を解説します。まずは、SumTreeとはどのような木なのかを確認しておきましょう。 SumTreeとは SumTreeとは、すべての内部ノードが「左の子と右の子の値の合計」を保持する特殊な二分木です。木の根(ルート)には、それより下位に存在する全要素の合計値が格納されます。なお、葉ノードのみからなる木や空の木も、定義上はSumTreeとみなされます。以下はSumTreeの一例です。 例えば上図の木では、根の値26が左部分木(10 + 4 + 6 = 20)と右部分木(3 + 3 = 6)の合計と一致しており