[Jacoste: 3] 타입변환과 시간복잡도

jabae·2022년 10월 23일
0

알고리즘 스터디

목록 보기
3/6

자바스크립트 스터디 3일차!! 이번주 부산도 놀러갔다 오고 이런저런 일들이 많았는데 용케도 풀었다. 다섯 문제... 역시 이래서 스터디를 하는가봉가 🧚‍♂️ 다들 열심히 해올 걸 생각하니 나도 게을리 할 수 없지!😏

오늘 휴지에게 들은 건데, 문제를 푸는 시간보다 풀고 나서 그 코드를 다듬는데 시간을 많이 쓴다고 한다.😲 거기서 얻는 게 크게 느껴진다고 하는데, 나도 틈틈이 풀었던 코드를 리팩토링해야겠다고 생각이 들었다. 그리고 앞으로 푸는 문제는 나도 리팩토링에 더 시간을 쏟아야겠다고 생각했다‼️

타입변환과 시간복잡도

k진수에서 소수 개수 구하기

저번 스터디 때 풀었던 문제였는데, 대킴🐻님이 메서드보다 for문이 더 빠른데, 왜 본인의 코드가 내 코드보다 시간이 느린지 모르겠다는 말로 시작이 되었다. 나는 filter() 안에서 함수를 호출해 for문을 돌고 대킴님의 코드는 이중 for문이었다. 코드상 둘 다 똑같이 시작복잡도는 O(N^2)일 것이란 말이지?

뿐만 아니라 휴지🐧 코드랑 구조적으로 굉장히 비슷하다고 생각했는데, 테스트 케이스 1번에서 휴지는 200ms, 나는 6ms 정도로, 꽤나 많은 차이가 났다. 아무리 뜯어봐도 너무 똑같은데🤔

그리고 시작된 시간 논쟁!

결론적으로는 타입변환에서 시간복잡도가 크게 올라간다는 사실을 알게 되었다‼️

split('0')으로 문자열로 변환된 수를 나🐰는 checkPrime(+x) 이렇게 함수에 타입변환을 해서 보내주고, 휴지🐧는 isPrime(el)이렇게 그냥 문자로 보내주었다. 그러면 함수에서 조건문을 확인할 때, 계속해서 암묵적 타입변환을 시켜주기 때문에 차이가 많이 났던 것이다.

대킴🐻님의 경우에도 조건문을 확인할 때, 계속 +N으로 +로 타입변환을 시켜주기에 그랬던 것이다! 이걸 빼니까 시간이 현저히 줄어들었다!

✅ 형변환을 시켜 인자로 넘겨줄 경우

function solution(n, k) {
    const checkPrime = (num) => {
        if (num === 2 || num === 3) return true
        if (!(num % 2)) return false;      
        for (let i = 3; i <= Math.sqrt(num); i += 2) {
            if (num % i === 0) return false;
        }
        return true
    }
    return n.toString(k)
            .split('0')
            .filter((x) => x !== '1' && x !== '' && checkPrime(+x)) // 형변환을 시켜 함수 인자에 담음!
            .length;
}

✅ 형변환을 안시키고 넘겨줄 경우

function solution(n, k) {
  function isPrime(n) {
    if (n <= 1) return false;
    for (let i = 2; i <= Math.sqrt(n); i++) {  // 반복문을 돌며
    	if (n % i === 0)                       // 여기서 n의 형변환이 계속 일어나는 것!
        	return false;
    }
    return true;
  }
  return n
    .toString(k)
    .split('0')
    .filter((el) => isPrime(el)) // 형변환을 시켜주지 않음!
    .length;
}

타입변환 때문에 이렇게 큰 차이가 나다니‼️
이런 발견을 하게 된 것도 신기하다.🧚‍♂️ 매일매일 스터디의 장점을 느끼고 있다.😊

그 외

Array.from() : 순서대로 배열 만들기

숫자를 순서대로 배열을 만들거나, 특히! 알파벳 순서대로 배열을 만들 유용하게 쓸 수 있다.

let arr = Array.from({length: 10}, (v, i) => i);

console.log(arr) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

let dic = Array.from({length: 26}, (v, i) => String.fromCharCode(i + 65));

console.log(arr) // ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

없는 숫자 더하기

조금만 더 생각하면 예쁘게 풀 수 있을 껄! 없는 숫자를 더하는 거이기 때문에 1부터 10까지 더한 다음 주어진 배열을 다 더한 값을 빼면 쉽게 풀 수 있을 껄 includes()를 써버렸다! 그제 공부한 시간복잡도O(n)인 메서드를 써버렸다! 지금은 간단한 문제지만 이 메서드를 쓰지 않아도 풀 수 있는 문제는 안쓰고 써 버릇 해야겠다.

profile
it's me!:)

0개의 댓글