Recent Posts
Recent Comments
Link
«   2024/09   »
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
Archives
Today
Total
관리 메뉴

kohigowild

221017 :: [프로그래머스] 하샤드 수, 2 X n 타일링, n^2 배열 자르기 본문

Algorithm

221017 :: [프로그래머스] 하샤드 수, 2 X n 타일링, n^2 배열 자르기

kohi ☕ 2022. 10. 18. 00:29
하샤드 수
👾 문제 설명
양의 정수 x가 하샤드 수이려면 x의 자릿수의 합으로 x가 나누어져야 합니다. 예를 들어 18의 자릿수 합은 1+8=9이고, 18은 9로 나누어 떨어지므로 18은 하샤드 수입니다. 자연수 x를 입력받아 x가 하샤드 수인지 아닌지 검사하는 함수, solution을 완성해주세요.

👾 제한 사항
  • x는 1 이상, 10000 이하인 정수입니다.

 

👾 나의 답안

function solution(x) {
    const arr = String(x).split("").map((x) => +x);
    return x % arr.reduce((a, b) => a + b) == 0 ? true : false;
}

 

  • x를 split한 배열 arr을 선언하고, x를 arr의 합으로 나눴을 때 나머지가 0이면 true를 반환하고 그렇지 않으면 false 반환

 


2 x n 타일링
👾 문제 설명

가로 길이가 2이고 세로의 길이가 1인 직사각형모양의 타일이 있습니다. 이 직사각형 타일을 이용하여 세로의 길이가 2이고 가로의 길이가 n인 바닥을 가득 채우려고 합니다. 타일을 채울 때는 다음과 같이 2가지 방법이 있습니다.

  • 타일을 가로로 배치 하는 경우
  • 타일을 세로로 배치 하는 경우

예를 들어서 n이 7인 직사각형은 다음과 같이 채울 수 있습니다.

직사각형의 가로의 길이 n이 매개변수로 주어질 때, 이 직사각형을 채우는 방법의 수를 return 하는 solution 함수를 완성해주세요.

👾 제한 사항
  • 가로의 길이 n은 60,000이하의 자연수 입니다.
  • 경우의 수가 많아 질 수 있으므로, 경우의 수를 1,000,000,007으로 나눈 나머지를 return해주세요.

 

👾 나의 답안

function solution(n) {
    const dp = [];

    for (let i = 2; i < n; i++) {
        dp[0] = 1;
        dp[1] = 2;
        dp[i] = (dp[i - 1] + dp[i - 2]) % 1000000007;
    }
    return dp[n - 1];
}

 

  • 첫 답안, 테스트 케이스는 전부 다 통과했으나 효율성 문제에서 시간 초과가 있었다.
  • n은 (n-1) + (n+2)의 값을 가진다. 피보나치 수열을 적용해 풀 수 있다. dp의 인덱스 0, 1에는 각각 1, 2로 값을 초기화하고 피보나치를 구현한다.
  • 효율성 문제가 있으면 BigInt를 붙여 보라길래 붙여봤는데 그것도 역시 효율성 문제가 있었다.

 

function solution(n) {
    let answer = 0;
    const dp = [1, 2];

    for (let i = 0; i < n; i++) {
        dp.push((dp[i] + dp[i + 1]) % 1000000007);
    }
    return (answer = dp[n - 1]);
}

 

  • 효율성 문제까지 전부 통과한 답안, dp 선언 시에 값을 넣어서 선언했고 이후 값들은 dp에 push 했다.

 


n^2 배열 자르기
👾 문제 설명
정수 n, left, right가 주어집니다. 다음 과정을 거쳐서 1차원 배열을 만들고자 합니다.
n행 n열 크기의 비어있는 2차원 배열을 만듭니다.i = 1, 2, 3, ..., n에 대해서, 다음 과정을 반복합니다.

1행 1열부터 i행 i열까지의 영역 내의 모든 빈 칸을 숫자 i로 채웁니다.
1행, 2행, ..., n행을 잘라내어 모두 이어붙인 새로운 1차원 배열을 만듭니다.
새로운 1차원 배열을 arr이라 할 때, arr[left], arr[left+1], ..., arr[right]만 남기고 나머지는 지웁니다.

정수 n, left, right가 매개변수로 주어집니다. 주어진 과정대로 만들어진 1차원 배열을 return 하도록 solution 함수를 완성해주세요.

👾 제한 사항
  • 1 ≤ n ≤ 107
  • 0 ≤ left  right < n2
  • right - left < 105

 

 

👾 제대로 구현도 못한 나의 첫 답안

 

  • 구현도 제대로 못해서 좀 부끄러운 답이지만... 열심히 풀어보고자 했던 흔적
  • 배열 타입이라도 제대로 나오는지 테스트 케이스 한 번 돌려보자 했는데 아예 돌아가지도 않음
  • 그나마 다행인 거는 코드 실행하는 잠깐 사이에 저 애니메이션에 낚이면 안 될 것 같다는 생각이 쓱 스치고 지나갔다는 점... 돈오점수인 듯

 

 

  • 배열로 생각하지 말고 그냥 이렇게 놓고 봤을 때 좌표 (x, y)의 값은 x > y ? x : y임 ㅋㅋㅋㅌㅋㅌㅋㅋㅌㅋㅌ킇ㅎ흨 (x와 y는 1부터 시작한다고 가정)
  • 근데 x, y와 주어지는 값들 사이에 어떤 연관 관계가 있는지는 모르겠어서 구글링의 힘을 조금 빌림 😅
    • left ~ right 범위의 임의의 숫자 num에 대해 x = Math.floor(num / n) | y = num % n
  • 이제 쉽게 구현할 수 있다!

 

👾 나의 답안

function solution(n, left, right) {
    let result = [];

    for (let i = left; i < right + 1; i++) {
        const x = Math.floor(i / n);
        const y = i % n;
        result.push(Math.max(x, y) + 1);
    }
    return result;
}

 

 

언제 봐도 좋구만