転置してから 各行を 逆にし、 正方形の 行列を 時計回りに 90 度回す
n×n の
海外で定番の問題リスト 4 本には入っていません
問題
写真のmatrix で
- 新しい
行列を 作らず、 matrixをその場で 書き換えてください。 書き換えた matrixを返す関数にします - 回した
あとの i 行 j 列には、 回す前の (n - 1 - j) 行 i 列の 値が 来ます。 左の 列が 下から 上へ 読まれて、 上の 行になります - n は 1 以上 20 以下、
値は どれも -1000 以上 1000 以下です
入力と出力の例
例 1
左の
例 2
2×2 では、
例 3
4×4 で、
面接での聞かれ方
面接では、
- 「正方形の
行列を 90 度回してください。 追加の 行列は 使わないでください」 - 新しい
行列に 書き写す 書き方を 見せると、 「その場でできますか?」と続きます - 書き終えた
あとに 「反時計回りなら、 どこを 変えますか?」と 聞かれる こともあります
1 つの
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
アルゴリズムのチートシートの「配列と文字列」に、
関わる学び
配列と
まず 考える手順
段 1
新しいout をout[i][j] = matrix[n - 1 - j][i] と
段 2
90 度の
段 3
転置は、j を i + 1 から
解答
Python
Python
def rotate_matrix(matrix):
n = len(matrix)
for i in range(n):
for j in range(i + 1, n):
a = matrix[i][j]
matrix[i][j] = matrix[j][i]
matrix[j][i] = a
for row in matrix:
row.reverse()
return matrixJavaScript
JavaScript
function rotateMatrix(matrix) {
const n = matrix.length;
for (let i = 0; i < n; i++) {
for (
let j = i + 1;
j < n;
j++
) {
const a = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = a;
}
}
for (const row of matrix) {
row.reverse();
}
return matrix;
}Go
Go
func rotateMatrix(
matrix [][]int,
) [][]int {
n := len(matrix)
for i := 0; i < n; i++ {
for j := i + 1; j < n; j++ {
m := matrix
m[i][j], m[j][i] =
m[j][i], m[i][j]
}
}
for _, row := range matrix {
l, r := 0, n-1
for l < r {
row[l], row[r] =
row[r], row[l]
l++
r--
}
}
return matrix
}Go にはslices.Reverse を
計算量
- 時間は O(n²) です。
転置で 約 n²/2 回、 反転で 約 n²/2 回入れ替えます。 どの 値も 1 回は 動かすので、 これより 速くは なりません - 追加の
記憶は O(1) です。 入れ替えに 使う 置き場だけです - 外側の
枠から 4 つの 値を 1 周ずつ回す 書き方 でも、 同じ O(n²) と O(1) になります
よく ある間違い
- 転置で
全部の 組を 入れ替える。 jを 0 から回すと、 i 行 j 列と j 行 i 列を 2 回入れ替えて 元に 戻ります。 対角線の 右上だけを回します - 反転を
列でしてしまう。 転置の あとに 上下を 反転すると、 反時計回りに 回った 形に なります。 時計回りは 各行の 左右の反転です - 新しい
行列に 書いて返す。 答えの 値は 合っていても、 「その場で」という 条件を 満たしません。 面接では、 条件を 守れているかを 先に言います - 入れ替えの
途中で 値を 上書きする。 置き場を 使わずに matrix[i][j] = matrix[j][i]だけを書くと、 元の matrix[i][j]が消えます
解答を動かした版 Python 3.14.7Node.js 24.22.1Go 1.24.2確認日 2026年11月8日
面接での 話し方の例
書き始める
「時計回りの 90 度は、
転置と、 各行の 左右の 反転の 2 つに 分けられます。 転置は 対角線の 右上だけを 左下と 入れ替え、 反転は 各行を 両端から 入れ替えます。 どちらも その 場の 入れ替えなので、 時間は O(n²)、 追加の 記憶は O(1) です。」
書き終えたら、
「例 2 の
[[1, 2], [3, 4]]をたどります。 転置で 2 と 3 を 入れ替えて [[1, 3], [2, 4]]です。各行を 反転して [[3, 1], [4, 2]]になり、 時計回りに 回った 形です。」