私があなたの問題を正しく理解しているなら、あなたは配列の中で最も高い比率A [j] / A[i]を持つi<jの2つのインデックス(i、j)を探しています。もしそうなら、あなたはそれをこの関連する問題に還元することができます、それはあなたにA [j]-A [i]ができるだけ大きくなるようにi≤jでインデックス(i、j)を見つけるように頼みます。この問題には、この問題にも適応できる非常に高速なO(n)時間、O(1)空間アルゴリズムがあります。直感は、配列の最初の要素だけで構成される配列の問題を解決し、次に最初の2つの要素、次に最初の3つの要素などを解決することです。配列の最初のn個の要素の問題を解決したら、問題に対する全体的な解決策があります。
これを行う方法を考えてみましょう。最初に、配列の最初の要素だけを検討する場合、要素をそれ自体と比較することで得られる最良の増加率は0%です。ここで、最初のk個の配列要素の問題を(帰納的に)解決し、次の配列要素を見たときに何が起こるかを確認したいとします。これが発生すると、2つの条件のいずれかが成立します。まず、最初のk要素に対する最大パーセンテージの増加は、最初の(k + 1)要素に対する最大パーセンテージの増加でもある可能性があります。たとえば、(k + 1)番目の配列要素が非常に小さい場合、最初のk要素の何かからその値まで大幅なパーセンテージの増加を得ることができない可能性があります。次に、最大パーセンテージの増加は、最初のk個の要素の1つから(k + 1)番目の要素までである可能性があります。
これらの2つのケースを組み合わせると、最初のk+1要素に対する最良の増加率は最大値であることがわかります。
- 最初のk個の要素の最大増加率、または
- 最初のk個の要素の最小値から(k + 1)番目の要素へのパーセンテージの増加。
これを実装するには、これまでに見た最小値とパーセント増加を最大化するペアの2つの値を追跡しながら配列要素全体を反復処理します。例として、元の例の配列の場合
1 2 3 10 1 20 40 60
アルゴリズムは次のように機能します。
1 2 3 10 1 20 40 60
min 1 1 1 1 1 1 1 1
best (1,1) (1, 2) (1, 3) (1, 10) (1, 10) (1, 20) (1, 40) (1, 60)
そして、最も高いパーセンテージの増加として(1、60)を出力します。このような別のアレイでは、次のようになります。
3 1 4 2 5
その場合、アルゴリズムは次のようにトレースします。3 1 4 2 5 min 3 1 1 1 1 best(3,3)(3,3)(1,4)(1,4)(1,5)
(1、5)を出力します。
このアルゴリズム全体はO(1)空間のみを使用し、O(n)時間で実行されます。これは、この問題に対する非常に優れたソリューションです。
または、配列内のすべての値の対数をとることで、この問題を直接最大の単一販売利益の問題に減らすことを考えることができます。その場合、log A [j] --log A [i]が最大化される値のペアを見つけた場合、これは(logarithmsのプロパティを使用して)log(A [j] / A [i])が最大化されます。対数関数は単調に増加しているため、これは、意図したとおりにA [j] /A[i]が最大化される値のペアが見つかったことを意味します。