정수 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
n | left | right | result |
---|---|---|---|
3 | 2 | 5 | [3,2,2,3] |
4 | 7 | 14 | [4,3,3,3,4,4,4,4] |
처음엔 누구나 생각할 수 있는 풀이를 했는데 역시나 런타임에러가 떴다.
두 번째 코드는 n^2배열이 만들어지는 룰을 보면 알 수 있다.
1번째 줄은 1,2,3,4..
2번째 줄은 2,2,3,4..
3번째 줄은 3,3,3,4...
4번째 줄은 4,4,4,4..
n번째 줄마다 n번째까지는 n이라는 숫자만 나온다.
따라서 left부터 right까지 반복을 해주고, Math.floor(i/n)과 i%n을 비교해 더 큰 숫자에 +1을 해주어 결과값에 추가해주면 된다.
예를 들어, 예시 1번을 보면 다음과 같다.
123
223
333
n=3 left=2 right=5
i/n | i%n |
---|---|
0 | 0 |
0 | 1 |
0 | 2 |
1 | 0 |
1 | 1 |
1 | 2 |
2 | 0 |
2 | 1 |
2 | 2 |
우리가 알아보기 쉽게 바꾸자면 다음과 같다.
i/n | i%n |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
2 | 2 |
2 | 3 |
3 | 1 |
3 | 2 |
3 | 3 |
왼쪽은 n번째 줄, 오른쪽은 순서를 나타낸다.
그런데 우리가 본 n^2배열은 2번째 줄은 [1,2,3]이 아닌 [2,2,3]이었고, 3번째 줄은 [3,3,3]이었다.
따라서 i/n과 i%n중에 더 큰 숫자를 선택하는 이유를 알 수 있다.
function solution(n, left, right) {
let answer = [];
let temp = 0;
for(let i=0; i<n; i++){
temp = i+1;
for(let j=0; j<temp; j++){
answer.push(temp);
}
for(let j=temp; j<n; j++){
temp++;
answer.push(temp);
}
}
answer = answer.slice(left, right+1);
return answer;
}
성공(9/20), 런타임에러(11/20)
function solution(n, left, right) {
let answer = [];
for(let i=left; i<=right; i++){
if(Math.floor(i/n) > i%n){
answer.push(Math.floor(i/n)+1);
}
else{
answer.push(i%n+1);
}
}
return answer;
}