✔️ 오늘의 리트코드 공부 기록 – Spiral Matrix
문제 요약 (Spiral Matrix)
MxN 행렬이 주어질 때,
시계 방향 나선형(spiral order) 으로 모든 원소를 순서대로 반환하는 문제.
문제링크: https://leetcode.com/problems/spiral-matrix/
🤔 처음 떠올린 아이디어
처음 문제를 봤을 때는 이런 생각이 들었다.
“방향 배열(dr, dc) 만들어서 계속 이동하다가 막히면 방향 바꾸면 되지 않을까?”
그래서
- visited[][] 배열을 두고
- 다음 칸이 범위를 벗어나거나, 이미 방문했다면 방향을 전환
이 방식이 가장 직관적으로 떠올랐다.
하지만 코드를 생각해보니
👉 visited 배열이 추가로 필요해서 공간 효율이 아쉽다는 느낌이 들었다.
💡 핵심 깨달음: 이 문제는 “이동”이 아니라 “경계” 문제다
이 문제를 계속 보다 보니 이런 구조라는 걸 깨달았다.
- 바깥 테두리를 한 바퀴 돈다
- 그 다음, 안쪽에 남은 작은 사각형을 다시 돈다
- 이 과정을 반복한다
즉, 이 문제는
한 칸씩 이동하는 문제가 아니라, 행렬을 레이어(layer) 단위로 깎아가는 문제
🧠 Boundary(경계) 방식으로 사고 전환
그래서 나는 행렬을 이렇게 바라보기로 했다.
rStart -------------- cEnd
| |
| |
| |
cStart ------------- rEnd
필요한 것은 딱 4개의 경계 변수다.
int rStart = 0;
int rEnd = matrix.length - 1;
int cStart = 0;
int cEnd = matrix[0].length - 1;
🔄 Boundary 방식의 고정된 순서
Boundary 방식에서는 순서가 곧 공식/로직이다.
- top row (왼 → 오)
- right column (위 → 아래)
- bottom row (오 → 왼)
- left column (아래 → 위)
한 바퀴를 돌면, 경계를 하나씩 줄인다.
⚠️ 반드시 필요한 조건 체크
아래 두 단계에서는 조건 체크가 필수다.
- bottom row
- left column
왜냐하면,
1×N, N×1 행렬처럼 중앙에 한 줄만 남은 경우 중복 방문이 발생할 수 있기 때문이다.
- if (rStart <= rEnd) { ... }
- if (cStart <= cEnd) { ... }
코드 (Java) | Spiral Matrix 풀이
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
int rStart = 0;
int rEnd = matrix.length - 1;
int cStart = 0;
int cEnd = matrix[0].length - 1;
while (rStart <= rEnd && cStart <= cEnd) {
// 1. top
for (int c = cStart; c <= cEnd; c++) {
result.add(matrix[rStart][c]);
}
rStart++;
// 2. right
for (int r = rStart; r <= rEnd; r++) {
result.add(matrix[r][cEnd]);
}
cEnd--;
// 3. bottom
if (rStart <= rEnd) {
for (int c = cEnd; c >= cStart; c--) {
result.add(matrix[rEnd][c]);
}
rEnd--;
}
// 4. left
if (cStart <= cEnd) {
for (int r = rEnd; r >= rStart; r--) {
result.add(matrix[r][cStart]);
}
cStart++;
}
}
return result;
}
}
📈 Time / Space Complexity
- 시간 복잡도: 모든 원소 1번 방문 → O(M×N)
- 공간 복잡도: 추가 배열 없음 → O(1)
❌ Boundary 방식 실수 TOP 5
1️⃣ rEnd / cEnd를 length로 두는 실수
- int rEnd = matrix.length; ❌ → 반드시 length - 1
2️⃣ bottom / left에서 조건 체크 누락
- 1×N, N×1 행렬에서 중복 추가 발생
3️⃣ 경계를 먼저 줄이는 실수
- 줄이고 → 읽기 ❌
- 읽고 → 줄이기 ⭕
4️⃣ while 조건을 OR로 쓰는 실수
- while (rStart <= rEnd || cStart <= cEnd) ❌ → 반드시 AND
5️⃣ 순서 변경
- Boundary 방식은 순서 자체가 로직이다.
- top → right → bottom → left (고정)
🧩 Boundary 일반화 공식
Spiral Matrix뿐 아니라 행렬 테두리 문제 전반에 그대로 적용 가능한 공식이다.
while (rStart <= rEnd && cStart <= cEnd) {
top
right
bottom (if needed)
left (if needed)
}
📝 이번 문제에서 얻은 깨달음
- Spiral 문제는 이동 문제가 아니라 경계 문제
- visited 방식은 직관적이지만, Boundary가 더 깔끔하다
- Boundary는 “기술”이 아니라 행렬을 바라보는 관점
- 👉 결국 중요한 건 “어떻게 움직이느냐”가 아니라 “어떻게 깎아나가느냐”였다.
'Algorithms' 카테고리의 다른 글
| [LeetCode] 56. Merge Intervals 풀이 (Java) (0) | 2026.01.21 |
|---|---|
| [LeetCode] 55. Jump Game 풀이 (Java) (1) | 2026.01.20 |
| [LeetCode] 53. Maximum Subarray 풀이 (Java) | Kadane 알고리즘 핵심과 오답 정리 (0) | 2026.01.18 |
| [LeetCode] 21. Merge Two Sorted Lists 풀이 (Java) (0) | 2026.01.17 |
| [LeetCode] 49. Group Anagrams 풀이 (Java) (0) | 2026.01.15 |