VIDTAKER.COM

Q&A

配列内の最も効率的に最小値を見つける


ある配列のNの値はであり、それらの1つの最小値です。どのように私は最も効率的に最小値を見つけることができますか?



8 Replies

1)

彼らが並べ替えられている場合は、大したことはできませんが、はO(N)が1つずつ、見て、いつあなたが最小値を知っているよ完了です。


擬似コード:

small = <biggest value> // such as std::numerical_limits<int>::max
for each element in array:
    if (element < small)
        small = element

より良い方法はで思い出したベンに最初の要素だったのでちょうど初期化小:

small = element[0]
for each element in array, starting from 1 (not 0):
    if (element < small)
        small = element

上記のに包まれているアルゴリズムのように、ヘッダstd::min_elementします。


あなたの配列を項目として整理しておくことができます場合は、フロントで最小を維持することができるので、それはO(1)される検索、追加されます。

それは配列で取得するようにそれは良いことだ。


2)

あなたは配列を、あなたは今まで見た中の最小値を覚えてもループが必要です。このように:

int smallest = INT_MAX;
for (int i = 0; i < array_length; i++) {
    if (array[i] < smallest) {
        smallest = array[i];
    }
}

3)

STLは問題に依存使用する必要がメソッドの束を含んでいます。

std::find
std::find_if
std::count
std::find
std::binary_search
std::equal_range
std::lower_bound
std::upper_bound

今では使用してどのようなアルゴリズムを含むデータの上にこのArtikelは含まれている完璧なテーブルアルゴリズムを右に役立つ選択します。


分の最大値は決定されるべきであるとは、std使用している:特殊なケースでは:ベクトルまたは???*配列

std::min_element
std::max_element

使用することができます。


4)

はO(1)sollution単に推測することがあります:あなたのアレイ内の最小数が多い0になります。 0作物をどこにでも。いる場合のみ、符号なしの数値を見ている考える。しかし、それでも数:0十分です。また、最小数のすべての要素を探して本当の痛みです。理由だけで使用しないで0?これは、実際正しい結果かもしれない!

1、2または3を試してインタビュアー/あなたの先生がいないその答えを、のような場合。また、ほとんどの宿題/インタビューシナリオ数値の配列になってしまっ...

:でもっと深刻な副作用どのくらいの頻度配列する操作を実行するこれにあなたが必要ですか?上記の取得箇所は、全てのO(n)がいるからです。あなたがしたい場合は、すべての時間に、なぜ前までいくつかの時間を払っていないとヒープを作成する新しい要素を追加されるリストにm回?次に、実際にはO(1)行うことができます、不正行為、結果なし最小の要素を見つける。


5)

最小値を見つける場合は1回のことだけで、リストを反復処理し最小値を見つけることです。

最小値を見つけることが非常に共通点れており、最低限の操作する必要があります、ヒープのデータ構造を使用します。

ヒープが速くリストに並べ替えを行うよりもなりますが、トレードオフはあなただけ最小値を求めることができます。


6)

あなた自身の配列の抽象化のいくつかの種類を開発している場合は、はO(1)あなたは格納する場合は最小の追加の属性の値を追加し、それに新しい項目は、配列に入れているすべての時間を比較することができます。

それはこのようになります:

class MyArray
{
public:
    MyArray() : m_minValue(INT_MAX) {}

    void add(int newValue)
    {
        if (newValue < m_minValue) m_minValue = newValue;
        list.push_back( newValue );
    }

    int min()
    {
        return m_minValue;
    }

private:
    int m_minValue;
    std::list m_list;
}

7)

これがゼロの配列サイズの失敗します。

#include <iostream.h>

double min(double *values, int size)
{
    double min = values[0];
    for (int i = 1; i < size; i++)
        if (values[i] < min)
            min = values[i];
    return min;
}

void main()
{
    double values[] = { 5, 4, 3, 2, 1, 6, 7, 8, 9, -53 };
    cout << min(values, sizeof(values) / sizeof(double));
}

他の言ったように、それは(n)は値の順序について欠席の知識のOだ、あなたは、単にそれらを反復処理するように。


8)

リッチーの答えは近くにあります。それは言語に依存します。ここでのJavaに適したソリューションです:

int smallest =  Integer.MAX_VALUE;
int array[]; // Assume it is filled.
int array_length = array.length;
for (int i = array_length - 1; i >= 0; i--) {
    if (array[i] < smallest) {
        smallest = array[i];
    }
}

"i"のを比較するので、私は逆の順序で配列を行く"array_length"ループの比較との比較(2つの操作)を取得し、比較一方、必要なの"i"を"0"は、単一のJVMのバイトコードの操作です。仕事がループ内で行われている場合は無視し、ループの比較は時間のかなりの部分を消費されます。

もちろん、他の人が、その配列と制御挿入をカプセル化に役立つと指摘した。最小値はすべての必要に応じていたなって、ソート順のリストを保持する場合は必要ありません。ただ、これまで挿入最小を保持するインスタンス変数を維持し、それぞれの値と比較することは配列に追加される。あなたは、要素を削除する場合(もちろん、これは失敗します。現在の最小値を削除する場合その場合、あなたは配列全体の新しい最小値を見つけるためにスキャンを実行する必要があります。)