안녕하세요

프로그래머스 JS [n^2 배열 자르기]⭐2차원배열 좌표 구하기 본문

프로그래머스/Lv.2

프로그래머스 JS [n^2 배열 자르기]⭐2차원배열 좌표 구하기

sakuraop 2022. 11. 28. 21:24

n^2 배열 자르기

문제 설명

정수 n, left, right가 주어집니다. 다음 과정을 거쳐서 1차원 배열을 만들고자 합니다.

  1. n행 n열 크기의 비어있는 2차원 배열을 만듭니다.
  2. i = 1, 2, 3, ..., n에 대해서, 다음 과정을 반복합니다.
    • 1행 1열부터 i행 i열까지의 영역 내의 모든 빈 칸을 숫자 i로 채웁니다.
  3. 1행, 2행, ..., n행을 잘라내어 모두 이어붙인 새로운 1차원 배열을 만듭니다.
  4. 새로운 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

입출력 예nleftrightresult
3 2 5 [3,2,2,3]
4 7 14 [4,3,3,3,4,4,4,4]

입출력 예 설명

입출력 예 #1

  • 다음 애니메이션은 주어진 과정대로 1차원 배열을 만드는 과정을 나타낸 것입니다.

문제 이해

gif를 보면 문제 자체를 이해하기는 쉬우나 제한사항을 보면
  • 1 ≤ n ≤ 10^7
이 있습니다.
배열을 만들면 시간초과가 나겠지만 우선 배열을 만들어 보았습니다. 
코드 해설(배열은 시간초과로 실패)

Array.from({length:n})으로 배열의 길이를 정하고,  
 const array = Array.from({ length: n }, () => Array.from({ length: n }, (_, i) => i + 1));

() => 콜백함수로 배열에 담을 요소를 정합니다.
여기서는 () => Array.from({ length: n }, (_, i) => i + 1)로 n만큼 인덱스마다 i+1을 넣습니다.
ex) n=3 일 때
=> [ [1,2,3],[1,2,3],[1,2,3] ]


만들어진 배열의 (i, j)에 i를 더해주도록 합니다.
    for (let i = 0; i < n; i++) {
        let plus = i;
        for (let j = 0; j < i; j++) {
            array[i][j] += plus;
            plus--;
        }
    }
ex) n=3일 때
[ [1,2,3],
[1,2,3],
[1,2,3] ] i=0

[ [1,2,3],
[2,2,3],
[2,2,3] ] i=1

[ [1,2,3],
[2,2,3],
[3,3,3] ] i=2


제출한 배열코드 (실패) 

function solution(n, left, right) {
    const array = Array.from({ length: n }, () => Array.from({ length: n }, (_, i) => i + 1));

    for (let i = 0; i < n; i++) {
        let plus = i;
        for (let j = 0; j < i; j++) {
            array[i][j] += plus;
            plus--;
        }
    }

    return array.join(",").split(",");.slice(left, right + 1).map((el) => parseInt(el));
}

solution(4, 7, 14);

🔻🔻🔻🔻🔻🔻🔻🔻🔻

규칙 찾기

// n=3
// 좌표/인덱스/값
// (0,0) 1 => 1
// (0,1) 2 => 2
// (0,2) 3 => 3
// (1,0) 4 => 2
// (1,1) 5 => 2
// (1,2) 6 => 3
// (2,0) 7 => 3
// (2,1) 8 => 3
// (2,2) 9 => 3

// (x,y) n*x + y + 1 => x,y 중 큰 수 + 1

행렬의 좌표별 인덱스와 값을 보면 규칙이 있습니다.

x는 i / n 을 내림한 값이고
y는 i % n 입니다.

        const x = Math.floor(i / n);
        const y = i % n


그리고 좌표에 해당하는 값의 규칙은 x와 y중 큰 수 + 1이 됩니다.

        answer.push(Math.max(x, y) + 1);

function solution(n, left, right) {
    const answer = [];

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

    console.log(answer);
    return answer;
}

solution(3, 2, 5);