코딩/프로그래머스 코딩테스트

[프로그래머스] 최소직사각형

민쯔 2021. 11. 9. 17:54
728x90
반응형

안녕하세요. 민쯔입니다.😊
프로그래머스 코딩 테스트 연습에서 Level 1이 3페이지가 있는데
드디어 첫 번째 페이지는 끝냈고 두 번째 페이지를 풀게 되었습니다.~~ 예이~~~!!🤩

 

본론으로 돌아와서 이번에는 최소직사각형을 구했는데요.
이번 문제는 쉬운편에 속하는 것 같고, 어떻게 더 간단하게 쓰는지에 따라 다른 것 같다는 생각이 들었어요.
그럼 최소직사각형 해결방안에 대해 설명해보겠습니다.

function solution(sizes) {    
    // 명함이 가로>세로 되도록 정렬하기
    sizes.map(s => s.sort((a, b) => b - a));

    // 가로, 세로 최댓값 구하기
    let maxW = Math.max.apply(null, sizes.map(s => s[0]));
    let maxH = Math.max.apply(null, sizes.map(s => s[1]));

    return maxW * maxH;
}

 

 먼저 문제 코드를 설명 전에 어떻게 풀었는지에 대해 설명하자면,

이 문제는 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다.  문제 설명을 쭉 읽다 보면 "명함을 가로로 눕혀 수납한다면" 이라는 문장이 나오는데,
이 말은 즉 가로, 세로를 고정을 할 필요가 없다는 겁니다.

그럼 테스트 1로 설명해보겠습니다.

테스트 1에서 가장 긴 가로길이와 세로 길이는 각각 80, 70입니다.
때문에 80(가로) x 70(세로) 크기의 지갑을 만들면 모든 명함들을 수납할 수 있습니다. 
하지만 2번 명함(w : 30, h : 70)을 가로로 눕혀 수납한다면 2번 명함(w : 70, h : 30)이 됩니다.

  • 가로 : 60, 70, 60, 80 -> 가로 최댓값 : 80
  • 세로 : 50, 30, 30, 40 -> 세로 최댓값 : 50

그래서 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다. 
이때의 지갑 크기는 4000(=80 x 50)이 됩니다.

 

여기서 알 수 있는 점은
명함의 가로, 세로의 크기를 비교하여 가로<세로 일 경우
가로, 세로를 바꾸어 가로 > 세로로 바꾸어 주고 가로, 세로의 최댓값을 뽑아 곱해주면 됩니다.

 

명함이 가로>세로 되도록 정렬하기

// 명함이 가로>세로 되도록 정렬하기
sizes.map(s => s.sort((a, b) => b - a)); // 오름차순

console.log(sizes);
// 테스트 1 [[60, 50], [70, 30], [60, 30], [80, 40]]

이 코드에서는
테스트 1 [[60, 50], [70, 30], [60, 30], [80, 40]] -> [[60, 50], [30, 70], [60, 30], [80, 40]]
으로 바꿔주어야 됩니다.

이번 문제가 sizes이 2차원 배열이라 일반적인 1차원 배열하고는 달라서 애를 먹었는데,
이럴 경우에는 map를 사용하면 편하더라고요.

  • map() : 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

MDN map() 메소드 예제

map() 안에 정렬 메서드인 sort()를 사용하여 가로, 세로를 오름차순으로 정렬해줍니다.

  • s.sort((a, b) => b - a) // 오름차순 정렬

sort() 메서드에 대해 알고 싶으시다면 아래 링크를 확인하시길 바랍니다.👇

https://minzz.tistory.com/48

 

자바스크립트 오름차순, 내림차순 구하기

안녕하세요. 민쯔입니다.😊 프로그래머스를 풀다 보니 오름차순, 내림차순을 만들일이 많아지더라고요. 그래서 이번에 자바스크립트로 오름차순 내림차순을 만드는 방법에 대해 설명하겠습니

minzz.tistory.com

프로그래머스에서 배열 정렬하기는 정말 많이 쓰이는 것 같아요.
그래서 배열 오름차순 내림차순은 외우는 게 좋을 것 같습니다.😀

 

가로, 세로 최댓값 구하기

// 가로, 세로 최댓값 구하기
let maxW = Math.max.apply(null, sizes.map(s => s[0]));
let maxH = Math.max.apply(null, sizes.map(s => s[1]));

console.log(sizes.map(s => s[0])); // 가로 [ 60, 70, 60, 80 ]
console.log(sizes.map(s => s[1])); // 세로 [ 50, 30, 30, 40 ]

return maxW * maxH;

가로, 세로의 최댓값을 구해야 되는데
최댓값 최솟값을 구하는 방법 중에서 가장 쉬운 방법이 Math.max.apply(null, Array);입니다.

그러나 Math.max.apply(null, Array);은 1차원 배열만 사용할 수 있어
2차원 배열을 1차원 배열로(가로, 세로 배열을 각각) 만들어서 넣었습니다.

  • Math.max() 함수는 입력값으로 받은 0개 이상의 숫자 중 가장 큰 숫자를 반환합니다.

그러나 Math.max()는 함수이기 때문에 () 안에는 파라미터만 받을 수 있습니다.
그래서 apply() 메서드를 사용해야 됩니다.

  • apply() 메서드는 주어진 this 값과 배열 (또는 유사 배열 객체)로 제공되는 arguments 로 함수를 호출합니다.

MDN Math, apply 사용하여 최댓값, 최솟값 구하기

 

Math.max.apply(null, Array);에서 Array에는 1차원 배열만 넣을 수 있기 때문에
다시 map() 메서드를 사용하여 가로, 세로 길이 배열을 만들었습니다.

  • sizes.map(s => s [0]); // 가로 [ 60, 70, 60, 80 ]
  • sizes.map(s => s [1]); // 세로 [ 50, 30, 30, 40 ]

 

마지막으로 가로 최댓값과 세로 최댓값을 곱하면 됩니다.

728x90
반응형