91. Decode Ways

  • 숫자둜 ν‘œν˜„λœ μ•ŒνŒŒλ²³ λ¬Έμžμ—΄μ„ 해석할 수 μžˆλŠ” 경우의 수λ₯Ό κ΅¬ν•œλ‹€.
    • 예λ₯Όλ“€μ–΄ 111은 aaa 1 1 1, ak 1 11, ka 11 1 둜 해석될 수 μžˆλ‹€.
    • 0의 경우 106은 1 06 κ³Ό 같이 μ•žμ— 0이 μ˜€λŠ” ν˜•νƒœλ‘œ λ¬Άμ–΄μ„œ 해석할 수 μ—†μŒμ— μ£Όμ˜ν•œλ‹€.
  • 첫번째 indexλΆ€ν„° 순차적으둜 해석을 μ§„ν–‰ν•œλ‹€.
    • ν˜„μž¬ 자리의 숫자λ₯Ό ν•΄μ„ν•˜κ³  indexλ₯Ό μ¦κ°€μ‹œν‚¨λ‹€.
    • μˆ«μžκ°€ 0이면 잘λͺ»ν•΄μ„ν•œ κ²ƒμ΄λ―€λ‘œ 경우의 μˆ˜κ°€ μ—†λŠ”κ²ƒ 0 으둜 ν•œλ‹€.
    • μˆ«μžκ°€ 1이고 λ‹€μŒ μˆ«μžκ°€ μ‘΄μž¬ν•˜λ©΄ ν˜„μž¬ 숫자만으둜 ν•΄μ„ν•œ 경우 index +1 + λ‹€μŒμˆ«μžκΉŒμ§€ λ¬Άμ–΄μ„œ ν•΄μ„ν•œ 경우 index +2의 수λ₯Ό λ”ν•œ 것을 결과둜 ν•œλ‹€.
    • μˆ«μžκ°€ 2이고 λ‹€μŒ μˆ«μžκ°€ 0~6인 경우 ν˜„μž¬ 숫자만으둜 ν•΄μ„ν•œ 경우 + λ‹€μŒμˆ«μžκΉŒμ§€ λ¬Άμ–΄μ„œ ν•΄μ„ν•œ 경우의 수λ₯Ό λ”ν•œ 것을 결과둜 ν•œλ‹€.
    • λ‚˜λ¨Έμ§€ κ²½μš°μ—λŠ” ν˜„μž¬ 숫자만으둜 ν•΄μ„ν•œ 경우의 수λ₯Ό λŒλ €μ€€λ‹€.
    • Indexκ°€ λ¬Έμžμ—΄ 끝에 λ„λ‹¬ν•œ 경우 해석할 수 μžˆλŠ” 경우의 μˆ˜λŠ” ν•œκ°€μ§€ λΏμ΄λ―€λ‘œ κ²°κ³Ό 값은 1이 λœλ‹€.
  • μœ„μ˜ λ‘œμ§μ„ κ·Έλƒ₯ κ΅¬ν˜„ν•˜κ²Œ 되면 μž¬κ·€ν˜ΈμΆœλ‘œ 인해 μ‹œκ°„ μ œμ•½μ— 걸릴 수 μžˆλ‹€.
    • 예λ₯Όλ“€μ–΄ 1둜만 이루어진 길이 인 λ¬Έμžμ—΄μ΄ μžˆμ„ λ•Œ μž¬κ·€ν˜ΈμΆœμ˜ μˆ˜λŠ” 이 λ˜λ―€λ‘œ λ¬Έμ œκ°€ 될 수 μžˆλ‹€.
    • μ–΄μ°¨ν”Ό νŠΉμ • index 이후λ₯Ό ν•΄μ„ν•˜λŠ” 경우의 μˆ˜λŠ” λ™μΌν•˜λ―€λ‘œ memoization을 μ΄μš©ν•˜μ—¬ μ€‘λ³΅λœ 연산을 쀄인닀.
class Solution { public int traverse(String s, int[] dp, int index) { if (dp[index] != -1) return dp[index]; int curr = s.charAt(index) - '0'; if (curr == 0) return dp[index] = 0; if (curr == 1 || curr == 2) { if (index + 1 < s.length()) { int next = s.charAt(index + 1) - '0'; boolean isValidNext = curr == 1 || (curr == 2 && next <= 6); if (isValidNext) { return dp[index] = traverse(s, dp, index + 1) + traverse(s, dp, index + 2); } } } return dp[index] = traverse(s, dp, index + 1); } public int numDecodings(String s) { int[] dp = new int[s.length() + 1]; Arrays.fill(dp, -1); dp[s.length()] = 1; return traverse(s, dp, 0); } }