다음 문제를 접근할 때 3가지를 고려했다.
1. 이중배열을 만들자
2. 배열끼리 붙이자
3. 자르자
즉, 규칙에 따라 n크기의 이중 배열을 만들고 그 배열을 다시 일차원 배열로 만들어 index left ~ right 까지
잘라 return 할 생각이었다. 하지만 이는 굉장히 오래 걸리는 문제가 있었다.
실제로 문제점수는 30점으로 효율성에서 모두 실패했다. 왜냐하면 n의 범위가 1에서 10의 7제곱까지이기때문이다.
항상 문제를 잘 읽어보아야겠다. 그래야 코드를 어떻게 짤지 방향을 잡을 수 있을 거 같다.
내가 실패한 코드는 다음과 같다.
function solution(n, left, right) {
const answers = [];
for (let i = 0; i < n; i++) {
const arr = [];
let count = 0;
for (let j = 0; j < n; j++) {
if (i >= j) {
arr.push(i + 1);
continue;
}
count = count + 1;
arr.push(i + 1 + count);
}
answers.push(arr);
}
let answer = [];
answers.forEach((item) => (answer = [...answer, ...item]));
return answer.slice(left, right + 1);
}
규칙성을 발견해 코드를 짠 것은 좋았지만 접근 방법이 좋지않았다.
사실 이 문제를 풀기위해 다른 분들의 힌트나 코드를 살펴보았다. 해법은 left와 right 그리고
규칙찾기에 있었다.
위와 같은 문제는
[1,2,3]
[2,2,3]
[3,3,3]
의 행렬이다.
(0,0) = 1 (0,1) = 2 (0,2) =3
(1,0) = 2 (1,1) =2 (1,2) = 3
(2,0) =3 (2,1) =3 (2,2) = 3
여기서 첫번 째 규칙성을 찾을 수 있다.
x,y좌표중 큰 수의 +1을 한 값이 해당 index의 값이다!
또, left와 right 값을 가지고 그 값이 있는 x,y좌표를 구할 수 있다.
[[1,2,3]
[2,2,3]
[3,3,3]]
위와 같은 이중배열이 있을 때 left 2는 (0,2) 이다 right 5는 (1,2) 이다
즉, x의 값은 left/3 의 몫이고 y의 값은 left %3 의 나머지이다.
그렇다면 두 번째 규칙은
위치/n 의 몫 => x 좌표
위치/n의 나머지 => y좌표
그럼 첫번째 규칙과 두 번째 규칙을 적용하여 반복문으로 문제를 해결할 수 있다.
function solution(n, left, right) {
const answer = [];
for (let i = left; i <= right; i++) {
// 범위를 이렇게 설정하여 left부터 right 까지 계산 할 수 있다.
answer.push(Math.max(i % n, Math.floor(i / n)) + 1);
// Math.floor를 사용하여 몫을 추출하고
// 둘 중 큰 값에 +1을 해준 후 answer에 넣어주면된다.
}
return answer;
}
위 문제는 규칙을 발견하고 적용하는게 key-point 였던 거 같다.