Java | 配列を逆順に並べ替える方法

Java Java
スポンサーリンク

今回は Java の配列を使った「配列を逆順に並べ替える(反転)」を完全攻略します。読みやすく段階を追っていきますね。

まずゴールを簡単に

配列 {12, 24, 18, 31, 17}{17, 31, 18, 24, 12} のように 順番を逆にする(左右を入れ替える)処理を実装します。
※目的は「配列の並びを反転すること」です。

基本アイデア

配列の「先頭」と「末尾」を入れ替える → 次に「先頭から2番目」と「末尾から2番目」を入れ替える → 中央まで繰り返す。
つまり左右から寄せていって入れ替えるだけ。

重要な概念(初心者がまず覚えるべき)

  • 配列のインデックスは 0 から始まる(例:長さ 5 の配列なら最後のインデックスは 4)。
  • 2つの要素を入れ替えるときは一時変数(temp)が必要(直接入れ替えると上書きされる)。
  • 反転は インプレース(元の配列をそのまま反転)新しい配列を作って反転コピー(元は残す) の2パターンがある。

サンプルコード(最も基本・分かりやすい:インプレースで反転)

import java.util.Arrays;

class ReverseExample {
    public static void main(String[] args) {
        int[] src = {12, 24, 18, 31, 17};
        System.out.println("元: " + Arrays.toString(src));

        // f = front index(先頭), l = last index(末尾)
        for (int f = 0, l = src.length - 1; f < l; f++, l--) {
            int temp = src[f];  // 先頭の値を退避
            src[f] = src[l];    // 末尾の値を先頭へコピー
            src[l] = temp;      // 退避しておいた先頭の値を末尾へコピー
        }

        System.out.println("反転後: " + Arrays.toString(src));
    }
}
Java
  • 実行結果:
    • 元: [12, 24, 18, 31, 17]
    • 反転後: [17, 31, 18, 24, 12]

行ごとのやさしい説明(上のコード)

  1. int[] src = { ... }:配列を作る。
  2. src.length - 1:配列の最後のインデックス(長さが5なら 4)。
  3. for (int f = 0, l = src.length - 1; f < l; f++, l--):先頭を f、末尾を l として、fl より小さい間だけループ。ループ内で f は右へ、l は左へ進む。
  4. int temp = src[f];f の値を一時的に保存(退避)。
  5. src[f] = src[l];l の値を f に入れる。
  6. src[l] = temp;:退避しておいた f の値を l に入れる(これで入れ替え完了)。

図で理解(配列長 5 の場合)

初期: indexes → 0 1 2 3 4
値 → 12 24 18 31 17

1回目(f=0,l=4)入れ替え:

  • swap src[0] と src[4]
    結果 → 17 24 18 31 12

2回目(f=1,l=3)入れ替え:

  • swap src[1] と src[3]
    結果 → 17 31 18 24 12

終了(f=2,l=2): 中央になったのでこれ以上交換しない(f < l が false)。

計算量(効率)

  • 時間計算量:O(n/2) → 通常は O(n)。(配列の半分だけ交換するため)
  • 空間計算量:O(1)。追加の配列を使わず、定数個の変数だけ使う。

別パターン:新しい配列を作って反転コピー(元は残す)

int[] src = {12, 24, 18, 31, 17};
int[] dst = new int[src.length];

for (int i = 0; i < src.length; i++) {
    dst[i] = src[src.length - 1 - i];
}
// dst は反転された配列、src は元のまま
Java
  • 使いどころ:元の配列を保持したいとき(非破壊的)。

応用例:String[] を反転

同じロジックで String[] でも動きます。

String[] names = {"Alice","Bob","Carol","Dave"};
for (int f=0, l=names.length-1; f<l; f++, l--) {
    String t = names[f];
    names[f] = names[l];
    names[l] = t;
}
Java

よくあるミス(初心者が陥りやすい)

  1. ループ条件を f <= l にしてしまう → 中央要素と自分自身を交換する(無害ですが不要)。ただし参照型であれば余計な操作になる。
  2. temp を使わずに src[f] = src[l]; src[l] = src[f]; のように書いてしまう → 上書きされて元の値が失われる(バグ)。
  3. インデックスの計算を間違える(src.lengthsrc.length - 1 の混同)。
  4. 範囲を部分的に反転したいときに境界を間違える(例:fromto をどう指定するか)。

部分だけを反転する(応用)

配列の一部 [from, to](インデックス)だけ反転したいとき:

void reverseRange(int[] a, int from, int to) {
    for (int f = from, l = to; f < l; f++, l--) {
        int t = a[f];
        a[f] = a[l];
        a[l] = t;
    }
}
Java

呼び出し例:reverseRange(arr, 1, 3); → インデックス 1〜3 が反転される。

練習問題 — 解答付き

問題1
int[] a = {1,2,3,4} をコードで反転するとどうなる?(手でシミュレート)

解答1
反転後 → {4,3,2,1}


問題2
String[] s = {"A","B","C"} に先ほどの in-place アルゴリズムを適用したら最終的にどうなる?

解答2
反転後 → {"C","B","A"}


問題3(少しチャレンジ)
長さ 6 の配列 {10,11,12,13,14,15}from=1,to=4 の部分だけ反転したら最終的な配列は?

解答3
部分 [1..4](11,12,13,14)を反転 → 14,13,12,11
最終配列 → {10,14,13,12,11,15}

まとめ(初心者が覚えるべき要点)

  • 反転は左右から寄せて入れ替えるだけ。fl を使う。
  • スワップには一時変数 temp が必要。
  • インプレース(破壊的)とコピーして作る(非破壊的)の2パターンがある。
  • ループは for (f=0, l=n-1; f<l; f++, l--) が定番。
  • 部分反転や型を変えた応用も簡単にできる。
タイトルとURLをコピーしました