https://school.programmers.co.kr/learn/courses/30/lessons/161990?language=javascript
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
입력
wallpaper (컴퓨터 바탕화면의 격자판. '#'는 파일 존재, '.'는 파일 없음을 나타낸다.)
출력
[행의 최솟값, 열의 최솟값, 행의 최댓값, 열의 최댓값]
제한사항
- 1 ≤ wallpaper의 길이 ≤ 50
- 1 ≤ wallpaper[i]의 길이 ≤ 50
- wallpaper의 모든 원소의 길이는 동일합니다.
- wallpaper[i][j]는 바탕화면에서 i + 1행 j + 1열에 해당하는 칸의 상태를 나타냅니다.
- wallpaper[i][j]는 "#" 또는 "."의 값만 가집니다.
- 바탕화면에는 적어도 하나의 파일이 있습니다.
- 드래그 시작점 (lux, luy)와 끝점 (rdx, rdy)는 lux < rdx, luy < rdy를 만족해야 합니다.
풀이
드래그를 해서 구할 수 있는 최소 직사각형을 구하는 문제이다. 이차원 배열이 주어지고 왼쪽과 위쪽에서 '#'이 있는 최소 위치를 구하고 마찬가지로 오른쪽과 아래쪽에서 '#'이 있는 최대 위치를 배열에 저장하면 된다. (이 때, 최대 위치는 조심해서 구해야 한다.)
가령, 아래의 표처럼 3*3의 정사각형 타일에 '#'이 가장 처음에 있다고 가정해보자. 최소 위치는 '#'이 있는 시작점인 [0, 0]이지만 최대 위치는 [1, 1]이다.
처음에는 어떻게 하면 시간 복잡도를 줄일까 고민했다. 이차원 배열이니 최소 행, 최소 열, 최대 행, 최대 열을 그냥 구하면 되지 않을까 고민했다. 그러나 최소와 최대 행을 구할 수 있었지만 결국 최소, 최대 열을 구하려면 모든 배열을 한 번 다 돌아야 하는 시간 복잡도 O(n*m)이 필요했다.
따라서 이중 for문을 사용하여 '#', 그러니까 파일이 있는 경우를 순회해야 했다. 정답을 쉽게 구하기 위해 미리 answer = [50, 50, 0, 0] 배열을 선언하였고 answer[0], answer[1]에는 최솟값이 들어가도록, 그리고 answer[2]와 answer[3]에는 최댓값이 들어가도록 하였다.
이때 Math 객체를 이용하여 최솟값, 최댓값으로 갱신해서 넣는다.
코드
명령형 프로그래밍으로 풀었다.
시간 복잡도는 이차원 배열를 모두다 순회하는 경우이므로 O(n*m)이다.
공간 복잡도는 정답을 저장하는 배열 하나이므로 O(1)이다.
function solution(wallpaper) {
var answer = [50, 50, 0, 0];
for (let i=0; i<wallpaper.length; i++) {
for (let j=0; j<wallpaper[0].length; j++) {
if (wallpaper[i][j] == '#') {
answer[0] = Math.min(answer[0], i);
answer[1] = Math.min(answer[1], j);
answer[2] = Math.max(answer[2], i+1);
answer[3] = Math.max(answer[3], j+1);
}
}
}
return answer;
}
선언형으로 풀기 위해서 알아보았으나 배열 두 개를 선언해야 하고 각각의 배열에 파일이 있는 모든 위치를 넣은 후에 최소와 최대를 구하는 구조였기에 시간 복잡도, 공간복잡도도 처음 풀이보다 컸기에 생략한다.
'Computer > 알고리즘' 카테고리의 다른 글
[JS] 프로그래머스 옹알이 (2) (0) | 2025.01.18 |
---|---|
[JS] 프로그래머스 햄버거 만들기 (1) | 2025.01.17 |
[JS] 프로그래머스 문자열 나누기 (0) | 2025.01.16 |
[JS] 프로그래머스 대충 만든 자판 (0) | 2025.01.15 |
[JS] 프로그래머스 덧칠하기 (2) | 2025.01.14 |