250x250
Notice
Recent Posts
Recent Comments
Link
반응형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- deque
- scanner
- set
- html
- 힙덤프
- map
- alter
- Java
- spring boot
- javascript
- JPA
- 리소스모니터링
- Union-find
- sql
- 큐
- math
- 스프링부트
- CSS
- dfs
- Calendar
- BFS
- union_find
- NIO
- List
- 스택
- GC로그수집
- date
- string
- priority_queue
- Properties
Archives
- Today
- Total
매일 조금씩
Leet code (Medium): 79. Word Search(DFS) - JAVA 본문
728x90
반응형
DFS를 다시 한번 제대로 복습할 수 있었던 문제다.
문제의 핵심은 다음과 같다.
- 주어진 목표 단어의 첫 알파벳과 일치하는 알파벳 칸을 발견하면 dfs 시작
- 한번 사용된 알파벳 칸은 재사용 안됨. Ex) "abca" 일 때, 처음 'a'때 방문한 칸을 마지막 'a' 때 재방문 할 수 없음.
- 따라서, 방문 체크 필요.
- 방문 체크는 해당 dfs 뎁스에서만 유효함. (다른 칸에서 dfs로 탐색이 시작되면 모든 칸은 방문되지 않은 상태여야 함)
- 따라서, 백트래킹 처리 필요
[방문 체크]
처음엔 방문 체크를 Set 객체를 사용해서 했는데 시간이 좀 오래걸려서
주어진 그래프 객체 board[row][col]를 업데이트하며 체크했다.
그랬더니 확연히 빨라졌다.
시간복잡도는 O(1)로 같겠지만,
아무래도 Set은 추가적인 메모리를 요구하고,
Set에 넣는 과정이 문자열을 조합해서 넣는 작업이다보니 좀 더 시간이 걸린것으로 보인다.
[백트래킹 처리]
현재 뎁스에서만 방문체크가 유효해야하므로,
백트래킹으로 dfs 재귀에서 빠져나올때, 방문체크를 해지하는 과정이 필요하다.
따라서, 방문 처리를 기존값을 무의미한 '*'로 업데이트 하고 있었기 때문에,
기존 board[row][col]의 값을 따로 temp로 저장해두고, dfs 재귀 호출 과정을 거친 후,
이후에 오는 백트래킹 작업으로 temp의 값을 다시 board에 업데이트 하는 식으로 구현했다.
class Solution {
private int rows;
private int cols;
private int[] dr = {-1, 0, 0, 1}; // 상, 좌, 우, 하
private int[] dc = {0, 1, -1, 0};
public boolean exist(char[][] board, String word) {
rows = board.length;
cols = board[0].length;
char[] charArr = word.toCharArray();
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
if (board[row][col] == charArr[0]) { // 첫 글자가 일치하면 DFS 시작
if (dfs(row, col, board, charArr, 0)) {
return true;
}
}
}
}
return false;
}
public boolean dfs(int currR, int currC, char[][] board, char[] charArr, int idx) {
// 재귀 종료 조건: 모든 문자를 찾은 경우
// (== 모든 문자를 찾고 난 직후인 경우)
if (idx == charArr.length) {
return true;
}
// 경계 체크 및 문자 일치 여부 확인
if (currR < 0 || currR >= rows || currC < 0 || currC >= cols || board[currR][currC] != charArr[idx]) {
return false;
}
// 현재 위치 방문 처리 (방문 여부를 보드 자체로 처리)
char temp = board[currR][currC]; // 백트래킹을 위한 임시 저장
board[currR][currC] = '*'; // 방문 처리
// 사방 탐색
for (int i = 0; i < 4; i++) {
int nextR = currR + dr[i];
int nextC = currC + dc[i];
if (dfs(nextR, nextC, board, charArr, idx + 1)) {
return true; // 경로가 유효하다면 true 반환
}
}
// 백트래킹: 방문 해제 (이전 상태로 되돌림)
board[currR][currC] = temp;
return false; // 모든 경로가 유효하지 않다면 false 반환
}
}
728x90
반응형
'알고리즘 > Matrix' 카테고리의 다른 글
Leet code (Medium): 48. Rotate Image - JAVA (0) | 2024.10.22 |
---|---|
Leet code (Medium): 54. Spiral Matrix - JAVA (0) | 2024.10.21 |
Leet code (Medium): 73. Set Matrix Zeroes - JAVA (0) | 2024.10.21 |