λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

μ•Œκ³ λ¦¬μ¦˜ λ¬Έμ œν’€μ΄/Programmers - Lv.2

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ Lv.2] 점프와 μˆœκ°„ 이동

풀이 λ‚ μ§œ : 2025.04.30
문제 μœ ν˜• : Summer/Winter Coding(~2018)
문제 제λͺ© : 점프와 μˆœκ°„ 이동
문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/12980

Intuition

  • μ£Όμ–΄μ§„ n만큼 μ΄λ™ν•˜λŠ” 데 ν•„μš”ν•œ μ΅œμ†Œν•œμ˜ 점프 횟수λ₯Ό κ΅¬ν•˜λŠ” λ¬Έμ œμ΄λ‹€.
    • μˆœκ°„μ΄λ™μ€ ν˜„μž¬κΉŒμ§€μ˜ 이동거리 * 2 의 μœ„μΉ˜λ‘œ μ΄λ™ν•˜κ³  건전지λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • μ ν”„λŠ” μ΄λ™ν•˜λŠ”λ§ŒνΌμ˜ 건전지λ₯Ό μ‚¬μš©ν•œλ‹€.
  • 그리디 μ•Œκ³ λ¦¬μ¦˜ : 항상 선택 κ°€λŠ₯ν•œ μ΅œμ„ μ˜ 방법을 μ„ νƒν•œλ‹€.
    • μˆœκ°„μ΄λ™μ„ μ΅œλŒ€ν•œ 많이 μ“°κ³ , μˆœκ°„μ΄λ™μ„ ν•  수 없을 λ•Œλ§Œ 점프λ₯Ό ν•΄μ•Ό ν•œλ‹€.
    • 6의 경우, [ 점프(0 + 1 = 1) → μˆœκ°„μ΄λ™(1 * 2 = 2) → 점프(2 + 1 = 3) → μˆœκ°„μ΄λ™(3 * 2 = 6) ] ⇒ μ΅œμ†Œ 2번의 점프가 ν•„μš”ν•˜λ‹€.
    • 6μ—μ„œ 0κΉŒμ§€ μ—­μœΌλ‘œ 생각해보면 μˆœκ°„μ΄λ™μ„ ν•  수 μžˆλŠ” 칸은 짝수 번째 칸이고, μˆœκ°„μ΄λ™μ„ ν•  수 μ—†λŠ” 칸은 ν™€μˆ˜ 번째 칸이닀.
  • λΉ„νŠΈ μ‘°μž‘ : κ·œμΉ™μ΄ 2의 배수, 짝/홀과 κ΄€λ ¨ 있음
    • 6을 μ΄μ§„μˆ˜λ‘œ λ³€ν™˜ν•˜λ©΄ 1010이고, [ 점프 → μˆœκ°„μ΄λ™ → 점프 → μˆœκ°„μ΄λ™ ] ⇒ μ΅œμ†Œ 2번의 점프가 ν•„μš”ν•˜λ‹€.
    • n을 μ΄μ§„μˆ˜λ‘œ λ°”κΎΈλ©΄ 1이 μžˆλŠ” μžλ¦¬λ§ˆλ‹€ μ ν”„ν•˜λŠ” 것과 κ°™λ‹€.

Approach

  • κ±΄μ „μ§€μ˜ μ‚¬μš©λŸ‰μ„ μ €μž₯ν•  λ³€μˆ˜(used)λ₯Ό μ„ μ–Έν•œλ‹€. 이 값은 점프 νšŸμˆ˜μ™€ κ°™λ‹€.
  • n이 0이 될 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.
    • n이 짝수면 n을 2둜 λ‚˜λˆˆλ‹€. (μˆœκ°„μ΄λ™, 건전지 μ‚¬μš© μ—†μŒ)
    • n이 ν™€μˆ˜λ©΄ nμ—μ„œ 1을 λΉΌκ³ , usedλ₯Ό 1 λŠ˜λ¦°λ‹€. (점프, μ ν”„ν•œ 만큼 건전지 μ‚¬μš©)
  • usedλ₯Ό λ°˜ν™˜ν•œλ‹€.

Complexity

  • Time complexity : O(log n)
    • 이동해야 ν•˜λŠ” 거리λ₯Ό n이라고 ν•  λ•Œ 계속 2둜 λ‚˜λˆ μ§€λ―€λ‘œ O(log n)이닀.
  • Splace complexity : O(1)
    • λ°°μ—΄μ΄λ‚˜ 객체 λ“±μ˜ 좔가적인 μ €μž₯ 곡간은 μ—†λ‹€.

Code (JS)

  • 그리디 μ•Œκ³ λ¦¬μ¦˜
function solution(n) {
    let used = 0;

    while (n !== 0) {
        if (n % 2 === 0) {
            n /= 2;
        } else {
            n -= 1;
            used += 1;
        }
    }

    return used;
}
  • λΉ„νŠΈ μ‘°μž‘
function solution(n) {
    let used = 0;
    while (n > 0) {
        used += n & 1;  // λ§ˆμ§€λ§‰ λΉ„νŠΈκ°€ 1이면(=ν™€μˆ˜λ©΄) 점프가 ν•„μš”
        n >>= 1;        // n을 였λ₯Έμͺ½μœΌλ‘œ 1λΉ„νŠΈ 이동 = n / 2
    }
    return used;
}