配列の最大値
配列を目で見れば、いちばん大きい数は一目で分かります。でもプログラムは配列を一望できません。前から 1 つずつしか見られない相手に、どうやって全体の中の一番を答えさせるかが今回の問題です。
途中経過を 1 つだけ持ち歩く
やり方は勝ち抜き戦と同じです。今のチャンピオンを 1 人だけ覚えておいて、より強い相手が現れたら王座を明け渡す。配列を最後まで見終わったとき、手元に残っているのが優勝者です。
最小値を探す例で見てみます。3 日分の最低気温から、いちばん寒かった日の気温を出します。
Java
int[] temps = {-3, -8, -1};
int min = temps[0];
for (int i = 1; i < temps.length; i++) {
if (temps[i] < min) {
min = temps[i];
}
}
System.out.println(min); // -8min は、ここまでで一番小さかった値を入れておくための変数です。ループの中でやっているのは、今見ている temps[i] と min を比べて、記録が更新されたときだけ書き換える、それだけです。
i が 1 から始まっているのは、temps[0] はもう min に入っているからです。0 から回しても答えは変わりませんが、自分と自分を比べる 1 周が無駄になります。
初期値を 0 にすると嘘をつく
いま min の初期値に temps[0] を使いました。ここを 0 から始めてはいけません。
Java
int[] scores = {72, 85, 60};
int min = 0; // 配列に存在しない値から始めてしまった
for (int i = 0; i < scores.length; i++) {
if (scores[i] < min) {
min = scores[i];
}
}
System.out.println(min); // 0。60 ではない72 も 85 も 60 も 0 より大きいので、更新が一度も起きません。結果、配列のどこにも入っていない 0 が答えとして返ってきます。
初期値は、必ず配列の中に実在する値から取ります。先頭の要素を使えば、それが保証されます。
先頭の要素が無い配列
初期値を先頭から取ると決めた瞬間に、気をつけることが 1 つ増えます。
Java
int[] empty = {};
int min = empty[0]; // ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0要素が 1 つも無い配列では、empty[0] を読んだ瞬間に落ちます。前回の 0 除算と同じで、これも入り口で引き返す話です。長さを確かめてから先頭を取りにいく、という順番を守ってください。
やってみよう
arrayMax は int[] から最大値を返します。上の最小値の例と違うのは、比べる向きだけです。
- 空の配列のときは
0を返します。先頭の要素に触る前に長さを確かめること {-1, -5, -3}を渡して-1が返るか必ず試してください。ここで0が返るなら、初期値の取り方を間違えています{42}のような要素 1 つだけの配列でも試しておきましょう。ループが 1 度も回らなくても答えが出る形になっていれば正解です
要件
- クラス名は
Solution、メソッド名はarrayMax、引数はint[] arrひとつにすること - 戻り値の型は
intで、配列の中の最大値を返すこと - 配列が空 (
arr.length == 0) のときは0を返し、負の数だけの配列でも正しく動くこと
入出力例
arrayMax([3,7,2,9,5]) → 9
arrayMax([-1,-5,-3]) → -1
arrayMax([]) → 0
arrayMax([42]) → 42
arrayMax([1,2,3,4,5]) → 5
arrayMax([10,3,8,1,6]) → 10