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

C++で多数派要素(マジョリティ要素)を判定する方法

ソート済みの配列が与えられたとき、指定した数値 x がその配列の多数派要素(マジョリティ要素)であるかどうかを判定する問題を考えてみましょう。ある要素が配列の半分を超える回数(n/2 回より多く)出現するとき、その要素を多数派要素と呼びます。

例えば、配列が {1, 2, 3, 3, 3, 3, 6} で x = 3 の場合を考えてみます。この配列には 3 が 4 回出現しており、配列のサイズは 7 なので、4 > 7/2 が成り立ちます。したがって、答えは true(3 は多数派要素である)となります。

アプローチ

最もシンプルな方法は、配列内に x が出現する回数を数え、その回数が n/2 より大きければ true を、そうでなければ false を返すというものです。配列がソートされているため、arr[i] が x より大きくなった時点でループを早期に終了することで、無駄な比較を省くことができます。

C++での実装例

#include <iostream>
using namespace std;

bool isMajorityElement(int arr[], int n, int x){
    int freq = 0;
    for(int i = 0; i < n; i++){
        if(arr[i] == x)
            freq++;
        if(arr[i] > x)
            break; // ソート済みなので、xより大きい値が出たら終了
    }
    return (freq > n/2);
}

int main() {
    int arr[] = {1, 2, 3, 3, 3, 3, 6};
    int n = sizeof(arr)/sizeof(arr[0]);
    int x = 3;
    if (isMajorityElement(arr, n, x))
        cout << x << " は配列の多数派要素です";
    else
        cout << x << " は配列の多数派要素ではありません";
}

入力

[1, 2, 3, 3, 3, 3, 6]
3

出力

3 は配列の多数派要素です

計算量と改善のポイント

上記の線形探索によるアプローチの時間計算量は O(n) です。ただし、配列がソート済みであることを活かせば、二分探索(lower_bound / upper_bound)を使って x の出現回数を O(log n) で求めることができ、全体の計算量を O(log n) まで改善できます。大規模な配列を扱う場合は、こちらの方法を検討するとよいでしょう。

  1. Javaでマジョリティ要素(多数派要素)を求める方法

    問題概要 整数の配列が与えられたとき、その中でマジョリティ要素(多数派要素)、すなわち配列のサイズの半分を超える回数出現する要素を見つけることを考えます。まずは具体的な例で確認してみましょう。 入力例1 − N = 8 A[ ] = { 1,2,4,3,3,1,1,5} 出力 − 1 説明 − 与えられた整数配列の中で最も多く出現している数字は「1」(3回出現)です。したがって、出力は「1」となります。 入力例2 − N = 6 A[ ] = {1,5,4,4,1,1} 出力 − 1 説明 − この配列でも「1」が3回出現しており、全体の半分を超えています。よって出力として「1」を返します。

  2. Pythonで配列のマジョリティ要素(過半数を占める要素)を見つける方法

    整数の配列が与えられたとき、その中で最も多く出現する要素(マジョリティ要素)を求めることを考えてみましょう。 問題の例 入力例1: N = 8A[ ] = { 1, 2, 4, 3, 3, 1, 1, 5 } 出力: 1 説明:この配列の中で最も多く出現している数は「1」です。したがって、出力は「1」となります。 入力例2: N = 6A[ ] = { 1, 5, 4, 4, 1, 1 } 出力: 1 説明:この配列でも最も多く出現しているのは「1」なので、「1」を結果として返します。 この問題へのアプローチ 配列に含まれる複数の整数の中から、最も頻度の高い要素を見つける必要があります。計算