나의 풀이
문제가 길어서 어려운 문제인가 싶었는데 다 읽고나니 괜히 겁먹었던 것 같다.
결론적으로 파일을 삭제하기 위해 드래그를 해야하는데
최소 사각형으로 드래그했을 때의 좌표값을 구하면 된다.
모든 #의 좌표를 구해서 최적의 lux,rdx luy,rdy를 구해도된다.
굳이 모든 좌표를 구해야 하나 싶어서 조금 더 생각해보았다.
상하좌우 각 끝점을 구하면 조금 더 쉽게 풀수 있을 것 같았다.
예를 들면 아래와 같다.
1. 맨 왼쪽에있는 파란색 파일의 luy = 3
2. 맨 위쪽에있는 하늘색 파일의 lux = 1
3. 맨 아래쪽에 있는 핑크색 파일의 rdx = 5
4. 맨 오른쪽에있는 빨간색 파일의 rdy = 8
1. 맨 왼쪽에 있는 파란색 파일 좌표 구하기(lux)
indexOf를 사용해주기
why? 맨왼쪽은 배열내에서 각 첫 번째 #을 뜻하기도 한다.
따라서 indexOf를 사용해주면 효과적이다.
그렇게해서 만약 문자열에 #이 존재하면 Math.min을 통해 최소값을 구하면된다.
for(let i = 0; i<wallpaper.length; i++) {
const firstFileIndexAtLeft = wallpaper[i].indexOf("#")
if(firstFileIndexAtLeft !== -1) {
left = Math.min(left, firstFileIndexAtLeft)
}
2. 맨 위쪽에 있는 하늘색 파일 좌표 구하기 (lux)
for(let i = 0; i<wallpaper.length; i++) {
const firstFileIndexAtLeft = wallpaper[i].indexOf("#")
if(firstFileIndexAtLeft !== -1) {
if(top === null) top = i
// left = Math.min(left, firstFileIndexAtLeft)
}
처음부터 null을 지정해주고 변수에 좌표가 할당되지 않았다면 할당해준다.
배열의 0 번째 문자열은 바탕화면 첫 번째 칸
1 번째 문자열은 바탕화면 두 번째 칸
2 번째 문자는 바탕화면 세 번째 칸을 뜻한다. 즉 0번째이든 1번째이든 n번째이든 n번째 문자열에서 처음 #이 나오면 그게 바로 맨 위쪽의 좌표가 된다.
3. 맨아래쪽에 있는 핑크색 파일 좌표 구하기(rdx)
for(let i = 0; i<wallpaper.length; i++) {
const firstFileIndexAtLeft = wallpaper[i].indexOf("#")
if(firstFileIndexAtLeft !== -1) {
// if(top === null) top = i
bottom = i + 1
// left = Math.min(left, firstFileIndexAtLeft)
}
매번 #이 발견될 때마다 bottom에 할당해주면된다.
그렇게되면 마지막 #이 발결되면 bottom에 할당되면서 맨 아래쪽 좌표가 나온다.
+ 1은 파일 아래쪽으로 좌표를 구하기 위해서이다.
4. 맨 오른쪽에있는 빨간색 파일의 좌표구하기(rdy)
for(let i = 0; i<wallpaper.length; i++) {
let firstFileIndexAtRight = wallpaper[i].lastIndexOf("#")
if(firstFileIndexAtRight !== -1) {
right = Math.max(right, firstFileIndexAtRight + 1)
}
}
왼쪽하고 방법이 같지만 각 문자열의 맨 뒤쪽부터 찾아야하기에 lastIndexOf를 사용해주면 된다.
그리고 오른쪽은 최소가아니라 최대값을 구해줘야한다. 최소값으로하면 맨 왼쪽 좌표가 된다.
전체 코드
function solution(wallpaper) {
let top = null
let bottom
let left = wallpaper[0].length
let right = 0
for(let i = 0; i<wallpaper.length; i++) {
const firstFileIndexAtLeft = wallpaper[i].indexOf("#")
if(firstFileIndexAtLeft !== -1) {
if(top === null) top = i
bottom = i + 1
left = Math.min(left, firstFileIndexAtLeft)
}
let firstFileIndexAtRight = wallpaper[i].lastIndexOf("#")
if(firstFileIndexAtRight !== -1) {
right = Math.max(right, firstFileIndexAtRight + 1)
}
}
return [top, left, bottom, right]
}
다른 사람 풀이
풀이 1)
모든 #의 좌표를 구해서 최소 최대로 구하는 방법이다.
wallpaper와 wallpaper[i]의 길이가 짧아서 나와 처리속도가 크게 차이가 나지는 않는다.
다만 나는 처음에 if문으로 최대최소를 구했는데 Math.max or min으로 사용하는게 더 가독성도 좋고 깔끔해서 나의 코드에 적용시켜주었다.
function solution(wallpaper) {
let left = [];
let top = [];
let right = []
let bottom = [];
wallpaper.forEach((v,i) => {
[...v].forEach((val,ind) => {
if(val === "#") {
left.push(i)
top.push(ind)
right.push(i + 1)
bottom.push(ind + 1)
}
})
})
return [Math.min(...left), Math.min(...top), Math.max(...right), Math.max(...bottom)]
}
풀이 2)
function solution(wallpaper) {
let [x1, y1, x2, y2] = [wallpaper.length, wallpaper[0].length, 0, 0];
// x1 => min i
// x2 => max i
// y1 => min idx
// y2 => max idx
wallpaper.forEach((paper, i) => {
if (paper.includes('#')) {
x1 = Math.min(x1, i);
y1 = Math.min(y1, paper.indexOf('#'));
x2 = Math.max(x2, i);
y2 = Math.max(y2, paper.lastIndexOf('#'));
}
});
return [x1, y1, x2 + 1, y2 + 1];
}
'알고리즘 > 프로그래머스 - JS' 카테고리의 다른 글
[프로그래머스] level.2 가장 큰수 😱 (0) | 2023.05.26 |
---|---|
[프로그래머스] level.3 베스트앨범 (0) | 2023.05.25 |
[프로그래머스] level.1 대충 만든 자판 (0) | 2023.05.23 |
[프로그래머스] level.2 다리를 지나는 트럭 (1) | 2023.05.22 |
[프로그래머스 - JS] level.2 프로세스 👍 (0) | 2023.05.20 |