[Level1] 4. 18 ~ 20
하루 세문제씩 꾸준히 풀기!
18. 없는 숫자 더하기
function solution(numbers) {
let sum = 0
for (let i = 0; i<numbers.length; i++){
sum += numbers[i]
}
return 45-sum;
}
맨날 어려운 문제 풀다가 1단계에서 정말 1단계스러운 문제를 오랜만에 만났다.
예전이었으면 0~9까지 하나하나 찾아서 없는 수를 알아냈겠지만 그동안의 경험으로
정석보다 더 빠른 풀이를 찾는 법을 알아낼 수 있게 되었다.
내가 접근한 방식은 0~9를 다 더한 수에서 numbers 빼기!
바로 정답이었고, 사람들의 풀이도 대부분 이 방식이었다.
best 풀이
function solution(numbers) {
return 45 - numbers.reduce((cur, acc) => cur + acc, 0);
}
배열에서 누적합을 구할 때는 reduce를 많이 쓴다는 것 잊지 말기!
19. 약수의 개수와 덧셈
function solution(left, right) {
let arr = []
let temp = []
let answer = 0
while(left <= right){
arr = [];
temp = []
for (let i = 0; i * i <= left; i++) {
if (left % i === 0) arr.push(i);
}
for (let i = 0; i < arr.length; i++) {
temp.push(parseInt(left / arr[i]));
}
let set = new Set(arr.concat(temp))
if (set.size % 2) {
answer -= left
} else {
answer += left
}
left++
}
return answer
}
풀긴 풀었는데 테스트케이스에서 어떤거는 5ms 가 나온정도로 시간복잡도가 최악인 경우가 있었다.ㅠ
16의 경우 4,4 로 나와서 중복 배제를 위해 어쩔 수 없이 set을 썼는데 여기서 시간복잡도가 크게 늘어나지 않았나 싶다.
약수의 갯수를 구하는 과정을 처음에는 정석으로 target % i === 0 인 것을 찾다가,
시간복잡도가 장난이 아니게 나올 것 같아서 검색한 결과 target의 제곱근 안에서만 구하고,
그 구한 수들로 target을 나눴을 때 몫까지 합하면 모든 약수라는 것을 배우고 다시 짰다!
확실히 코테는 문제를 많이 접하면 접할 수록 효율적인 접근 방법을 많이 배울 수 있는 것 같다.
best 풀이
function solution(left, right) {
var answer = 0;
for (let i = left; i <= right; i++) {
if (Number.isInteger(Math.sqrt(i))) {
answer -= i;
} else {
answer += i;
}
}
return answer;
}
우와 정말 간단한 코드…!
제곱근이 정수면 약수의 갯수가 홀수라는 수학적 원리를 이용한 풀이법이다.
이건 정말 일반인이 알아낼 수 있는 공식인걸까?
나는 이걸 하려고 set도 쓰고 안간힘을 썼는데….
Math.sqrt() : 숫자의 제곱근 반환
기억하기
정석 풀이법
function solution(left, right) {
let answer = 0;
for (let i = left; i <= right; i++) {
let count = 0;
for (let j = 1; j <= i; j++) {
if (i % j === 0) count++;
}
if (count % 2) answer -= i;
else answer += i;
}
return answer;
}
어찌보면 이게 내 코드보다 더 단순한 것 같다…
비교 대상 수가 엄청 큰 수가 아니라면 이게 더 빠를 수도 있을 것 같다. (가시적으로는 이게 훨씬 좋아보이네..쩝)
20. 모의고사
function solution(answers) {
let num1 = [1, 2, 3, 4, 5];
let num2 = [2, 1, 2, 3, 2, 4, 2, 5];
let num3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5];
let length = [5, 8, 10];
let cnt = new Array(3).fill(0);
for (let i = 0; i < answers.length; i++) {
if (num1[i % length[0]] === answers[i]) {
cnt[0]++;
}
if (num2[i % length[1]] === answers[i]) {
cnt[1]++;
}
if (num3[i % length[2]] === answers[i]) {
cnt[2]++;
}
}
let max = Math.max(...cnt);
let arr = [];
cnt.forEach((item, index) => {
if (item === max) {arr.push(index+1);}
});
return arr.sort((x, y) => x - y)
}
정답은 맞았는데 뭔가 별로다..
저번부터 조건에 만족하는 수를 배열에서 찾아 그것의 인덱스로 반환하는게 나한테 너무 힘들었다.ㅠㅠ
forEach를 쓰면 된다는 것을 오늘에서야 깨달았다…ㅋㅋㅋ 그동안 왜몰랐지? 바본가..?
그래도 잘 활용해서 풀었으니 된거다! 더 발전했으면 됐어!
다른 풀이를 보니까 접근방식이 모두 동일해서 엄청 못한 것 같지는 않으니 합격!
best 풀이
function solution(answers) {
var answer = [];
var a1 = [1, 2, 3, 4, 5];
var a2 = [2, 1, 2, 3, 2, 4, 2, 5]
var a3 = [ 3, 3, 1, 1, 2, 2, 4, 4, 5, 5];
var a1c = answers.filter((a,i)=> a === a1[i%a1.length]).length;
var a2c = answers.filter((a,i)=> a === a2[i%a2.length]).length;
var a3c = answers.filter((a,i)=> a === a3[i%a3.length]).length;
var max = Math.max(a1c,a2c,a3c);
if (a1c === max) {answer.push(1)};
if (a2c === max) {answer.push(2)};
if (a3c === max) {answer.push(3)};
return answer;
}
정답을 찾는 접근법은 나랑 똑같은데 훨씬 간결한 코드와 적합한 메소드를 사용해서 코드가 짧아진 것 같다.
오늘은 조금 쉬고 싶어서 자료구조가 들어간 문제를 풀지 않았는데 내가 약한건 자료구조가 녹여진 문제라는 걸 안다…내일부터는 피하지말고 부딪치자!!👑👑