これは学校の割り当てですが、プログラムは「最大のパフォーマンスで実装されている」という要件でした。メモリがスピードを上回るかどうかなど知っているだろう。しかし、私が探しているのは、入力データに対してスマートな操作を行うことで問題を解決する "トリッキーな"方法があるかどうかである。整数が整数の和の1つであるかどうかを調べる効率的な方法
だから、ここで問題があります:A.
の任意の2つの 以降の要素の和に等しいBでこのような整数がある場合は1を返す関数を、書く、あなたは二つの配列、AとBを持って考えます以下は私の書き上げです。 Hashmap<Integer>
を使用しなかったことに注意してください。なぜなら、スピードアップに必要なメモリは、O(n * m)のスピードでO(n *)の代わりに最悪の場合のスピードで十分に不利なものだと考えていたからです。
public static int arrayContainsSum(int[] a, int[] b)
{
int offsetA = a.length - 1;
int offsetB = offsetA;
int index = b.length - 1;
int result = 0;
int tested;
while (index >= 0)
{
if (offsetA > 0) a[offsetA] += a[--offsetA];
else if (offsetA == 0) // This has a danger of overflowing the int
a[offsetA--] = multiply(a);
tested = b[index];
if ((offsetA < 0 && tested != 0 && a[0] % tested != 0) ||
offsetB == 0)
{
// No point to test this element as it doesn't
//divide the product of sums
offsetB = a.length - 1;
index--;
}
if (tested == a[offsetB--])
{
result = 1;
break;
}
}
return result;
}
private static int multiply(int[] input)
{
int accumulator = input.length > 0 ? 1 : 0;
for (int i : input)
if (i != 0) accumulator *= i;
return accumulator;
}
私が心配していないことがいくつかあります:整数のオーバーフロー(乗算の結果として起こりうる)。私はarray.length
がローカル変数からの読み込みと同じくらい速いと仮定しました。
しかし、私の質問はむしろ「分析的にこの問題を解決することはできませんでしたか?より良い効率を意味するでしょうか?
PS。この問題には、配列にユニークなメンバーしか含まれていないことは言及されていません。私はまた、a
をソートすることによって最適化することが可能であると考えているので、がa
の最小要素より小さく、次にa
の最大要素よりも小さい場合は、いくつかのルックアップを保存します。これもまた複雑さが増し、恐らく完全に正当化されないであろう。
私はあなたの質問が何を意味するか分かりません。この場合、分析的にはどういう意味ですか? –
O(1)メモリでこれを行いたい場合は、配列をソートしてバイナリ検索を行う方が良いでしょう(aとbは配列のサイズです):O(a * b) a + b * log a)である。 a == bの場合は、O(a^2)とO(aログ)です。最適なアルゴリズムは、あなたがすでに知っているように、O(a)余分なメモリを持ちますが、O(b)時間で実行されます。 – Voo
私は何故乗算を呼び出す必要があるのか理解できないと言わなければなりません(あなたのコードが何をしているのか分かりませんでしたが、これは私の目立つものです...) –