작성일 : December 31, 2021
문제 : https://programmers.co.kr/skill_checks/335618?challenge_id=9645
해설 : https://velog.io/@front/프로그래머스-n2-배열-자르기
function solution(n, left, right) {
const table = Array(n).fill().map(() => Array(n));
const result = [];
for(let i=0; i<n; i++) {
for(let j=0; j<n; j++) {
if(j-i <= 0) {
table[i][j] = i+1;
} else {
table[i][j] = table[i][j-1] + 1;
}
}
}
table.forEach(arr => result.push(...arr));
return result.filter((v,i) => {
if(i>= left && i<=right) return v;
});
}
/*
채점 결과
정확성: 15.0
효율성: 0.0
합계: 15.0 / 50
*/
주먹구구식문제에서 나온 방법대로 2차원 배열을 생성한 다음, 각 행을 이어 붙여서1차원화 한 다음 left ~ right
의 숫자를 담아도 되겠지만,n
은 무려 10^7
까지 인풋으로 주어집니다.이 방법으론 시간과 공간 효율성에서 통과하지 못하겠네요.
좌표로 전환해서 생각문제 설명에서도, gif에서도 보이듯 아시겠지만 좌표 (r, c)
에 들어갈 숫자는 max(r, c) + 1
이 됩니다.그러면 left ~ right
범위의 숫자를 좌표로 변환만 해주면 문제가 쉽게 해결되겠네요.결론부터 말씀드리자면left ~ right
범위의 임의의 숫자 num
에 대해서 좌표 (r, c)
를 구하는 공식은
r = floor(num / n)
c = num % n
입니다.이제 코드로 구현만 하면 됩니다.
function solution(n, left, right) {
const ans = [];
while (left <= right) {
ans.push(Math.max(Math.floor(left / n), left++ % n) + 1);
}
return ans;
}
수학적 재능이 필요한걸까 ...