오늘의 문제는 프로그래머스
바탕화면 정리
문제
문제 설명
바탕화면의 파일을 삭제해 정리하려고 합니다. 바탕화면은 정사각형의 격자판이고 바탕화면의 상태를 나타내는 문자열 wallpaper가 주어집니다. 가장 왼쪽 위 (0, 0) 부터 시작해서 파일이 있는 칸은 "#", 파일이 없는 칸은 "." 이라고 했을 때 드래그로 파일을 선택해 한 번에 지워야 합니다.
드래그는 격자점 S(lux, luy)를 마우스 왼쪽 버튼으로 클랙한 상태로 격자점 E(rdx, rdy)로 이동한 다음 마우스 왼쪽 버튼을 떼는 것을 말합니다.
S를 시작점, E를 끝점이라고 할 때 드래그의 한 거리 |rdx - lux| + |rdy - luy| 값이 최솟값일 때의 정수 배열 [lux, luy, rdx, rdy]를 반환하는 문제입니다.
입력 값이 wallpaper = [".#...", "..#..", "...#."] 일 때 반환 값은 [0, 1, 3, 4] 입니다.
문제 풀이 시간
권장 풀이 시간은 60분이었고, 저는 51분이 걸렸습니다.
문제 접근 방식
먼저 wallpaper가 1차원 배열로 주어졌기 때문에 이를 2차원 배열로 변환하여 격자판을 생성합니다. 이중 for문을 사용해 2차원 배열의 요소를 순회하고 값이 #인 경우 해당 위치의 행과 열을 각각 ArrayList에 저장합니다. 반복문이 끝나면, 저장된 ArrayList 를 오름차순으로 정렬하고 첫 번째 요소와 마지막 요소를 변수에 저장하여 결과로 반환합니다.
문제 풀이
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Comparator;
class Solution {
public int[] solution(String[] wallpaper) {
int row = wallpaper.length;
int col = wallpaper[0].length();
String[][] wallPaper = new String[row][col];
for(int i = 0; i < row; i++) {
for(int j = 0; j < col; j++) {
wallPaper[i][j] = String.valueOf(wallpaper[i].charAt(j));
}
}
ArrayList<Integer> rows = new ArrayList<Integer>();
ArrayList<Integer> cols = new ArrayList<Integer>();
for(int i = 0; i < row; i++) {
for(int j = 0; j < col; j++) {
if(wallPaper[i][j].equals("#")) {
rows.add(i);
cols.add(j);
}
}
}
rows.sort(Comparator.naturalOrder());
cols.sort(Comparator.naturalOrder());
int lux = rows.get(0);
int rdx = rows.get(rows.size() - 1) + 1;
int luy = cols.get(0);
int rdy = cols.get(cols.size() - 1) + 1;
int[] answer = {lux, luy, rdx, rdy};
return answer;
}
}
rdx와 rdy의 값을 1 증가시키는 이유
마지막 값에 1을 더하는 이유는, # 문자가 위치한 마지막 행과 열을 나타내는 값은 해당 문자가 포함된 행과 열의 시작점을 나타내기 때문입니다. 하지만 사각형의 범위를 정확하게 정의하려면 그 끝점을 포함해야 합니다. 따라서 rdx와 rdy에 1을 더해줌으로써, 해당 문자가 포함된 마지막 행과 열의 끝점까지 포함하여 사각형의 범위를 정확하게 나타낼 수 있습니다.
코드 개선하기
기존 코드에서 사용하던 이차원 배열을 제거하고 String[] wallpaper 배열에서 바로 charAt 메서드를 사용해 문자를 비교하는 방식으로 수정했습니다.
import java.util.ArrayList;
import java.util.Comparator;
class Solution {
public int[] solution(String[] wallpaper) {
int row = wallpaper.length;
int col = wallpaper[0].length();
ArrayList<Integer> rows = new ArrayList<>();
ArrayList<Integer> cols = new ArrayList<>();
for(int i = 0; i < row; i++) {
for(int j = 0; j < col; j++) {
if(wallpaper[i].charAt(j) == '#') {
rows.add(i);
cols.add(j);
}
}
}
rows.sort(Comparator.naturalOrder());
cols.sort(Comparator.naturalOrder());
int lux = rows.get(0);
int rdx = rows.get(rows.size() - 1) + 1;
int luy = cols.get(0);
int rdy = cols.get(cols.size() - 1) + 1;
return new int[]{lux, luy, rdx, rdy};
}
}
다른 풀이
아래 코드는 wallpaper 배열에서 # 문자가 포함된 사각형의 경계를 나타내는 좌표를 계산합니다.
이중 for문을 사용해 wallpaper의 모든 요소를 순회합니다. wallpaper[i].charAt(j) == '#' 조건을 통해 # 문자가 있는 위치를 확인합니다. 각 #의 좌표를 추적해 현재까지 발견된 최소 및 최대 좌표와 비교합니다.
최종적으로 minX와 minY는 사각형의 가장 왼쪽 위를 나타내고, maxX와 maxY는 가장 오른쪽 아래를 나타냅니다.
class Solution {
public int[] solution(String[] wallpaper) {
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
for(int i=0; i< wallpaper.length;i++ ){
for(int j=0; j<wallpaper[i].length();j++){
if(wallpaper[i].charAt(j)=='#'){
minX = Math.min(minX,i);
minY = Math.min(minY,j);
maxX = Math.max(maxX,i);
maxY = Math.max(maxY,j);
}
}
}
return new int[]{minX,minY,maxX+1,maxY+1};
}
}
이렇게 오늘 26일차 TIL을 작성해 보았습니다.
'🍪 Ect > #Study' 카테고리의 다른 글
[99클럽 코테 스터디] 28일차 TIL 스택/큐 (0) | 2024.08.18 |
---|---|
[99클럽 코테 스터디] 27일차 TIL 시뮬레이션 (0) | 2024.08.17 |
[99클럽 코테 스터디] 25일차 TIL 그래프 (0) | 2024.08.15 |
[99클럽 코테 스터디] 24일차 TIL 그래프 (0) | 2024.08.14 |
[99클럽 코테 스터디] 23일차 TIL 그리디 (0) | 2024.08.13 |
댓글