823. Binary Trees With Factors

  • Array arr에 μžˆλŠ” 숫자λ₯Ό μ΄μš©ν•΄μ„œ λ§Œλ“€ 수 μžˆλŠ” 트리의 경우의 수λ₯Ό κ΅¬ν•˜λŠ” 문제.
    • 트리의 non leaf node μˆ«μžλŠ” child node 숫자의 곱으둜 κ²°μ •λ˜μ–΄μ•Όν•˜λŠ” κ·œμΉ™μ΄ μžˆμœΌλ―€λ‘œ 이λ₯Ό λ°”νƒ•μœΌλ‘œ 경우의 수λ₯Ό 계산해보면 λœλ‹€.
    • μ²˜μŒμ—λŠ” 두 숫자의 쑰합을 λ°”νƒ•μœΌλ‘œ 숫자의 곱이 array arr에 μ‘΄μž¬ν•˜λŠ”μ§€ μ²΄ν¬ν•˜κ³  있으면 이λ₯Ό λ°”νƒ•μœΌλ‘œ 트리λ₯Ό λ§Œλ“€μ–΄ root λΆ€ν„° νƒμƒ‰ν•˜λŠ” 방식을 μ·¨ν–ˆλ‹€.
    • child node 의 μˆ«μžκ°€ λ‹€λ₯Έ 경우
      • , 두 κ°€μ§€ μˆœμ„œμ— λŒ€ν•œ μ‘°ν•©μ˜ 숫자 + parent node ν•˜λ‚˜λ§ŒμœΌλ‘œ κ΅¬μ„±λœ 트리
    • child node의 μˆ«μžκ°€ 같은 경우
      • , 두 κ°€μ§€ μˆœμ„œμ— λŒ€ν•œ μ‘°ν•©μ˜ 숫자 ( 경우의 수λ₯Ό μ œμ™Έ) + parent node ν•˜λ‚˜λ§ŒμœΌλ‘œ κ΅¬μ„±λœ 트리
    • 이런 λ°©μ‹μœΌλ‘œ μ ‘κ·Όν–ˆμœΌλ‚˜ 일뢀 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ—μ„œ μ‹€νŒ¨ν–ˆμœΌλ©° 원인을 μ°Ύμ§€ λͺ»ν•΄μ„œ 해닡을 μ°Έμ‘°ν–ˆλ‹€.
  • child node 숫자 μ‘°ν•©μ—μ„œ parent node 숫자λ₯Ό λ§Œλ“€μ–΄λ‚΄λŠ” λ°©μ‹λ³΄λ‹€λŠ” λ°˜λŒ€λ‘œ μ ‘κ·Όν•˜λŠ” 방식이 더 효율적이고 μ‰½κ²Œ ν’€ 수 μžˆλŠ” κ²ƒμœΌλ‘œ μƒκ°λœλ‹€.
  • 풀이 방식은 λ‹€μŒκ³Ό κ°™λ‹€.
    • λ¨Όμ € array arrλ₯Ό μž‘μ€ μˆ«μžκ°€ μ•žμœΌλ‘œ μ˜€λ„λ‘ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬ν•œλ‹€.
    • 각 node 별 κ²°κ³Όλ₯Ό κ³„μ‚°ν•˜μ—¬ μ €μž₯ν•œλ‹€.
    • root node와 factor node (child node) 쑰합을 κΈ°μ€€μœΌλ‘œ λ‚˜λ¨Έμ§€ child nodeλ₯Ό κ³„μ‚°ν•œλ‹€.
      • root μˆ«μžκ°€ factor둜 λ‚˜λ‰˜μ§€ μ•ŠλŠ”λ‹€λ©΄ ν•΄λ‹Ήλ˜λŠ” child node 쑰합이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” κ²ƒμ΄λ―€λ‘œ skip ν•œλ‹€.
      • λ‹Ήμ—°ν•˜μ§€λ§Œ factorκ°€ rootλž‘ κ°™κ±°λ‚˜ 크면 child node 쑰합이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ (μˆ«μžλŠ” 1보닀 큰 값이어야 ν•˜λ‹ˆκΉŒ) skip ν•œλ‹€.
      • λ‚˜λ¨Έμ§€ λ…Έλ“œ quotientλŠ” root / factor둜 κ²°μ •λœλ‹€.
    • ν˜„μž¬ λ…Έλ“œ root의 경우의 μˆ˜λŠ” factor, quotient node 각각의 경우의 수의 곱의 합이닀.
    • μ΄λ ‡κ²Œ κ³„μ‚°λœ 각 λ…Έλ“œ 별 경우의 수 subResult λ₯Ό λͺ¨λ‘ λ”ν•˜λ©΄ 전체 경우의 μˆ˜κ°€ λœλ‹€. 여기에 λͺ¨λ“ˆλŸ¬ 연산을 ν•˜λ©΄ λœλ‹€.
class Solution { public: static constexpr int MOD = 1e9 + 7; int numFactoredBinaryTrees(vector<int>& arr) { sort(arr.begin(), arr.end()); long long result = 0; unordered_map<int, long> subResult; for (auto root : arr) { subResult[root] = 1; for (auto factor : arr) { if (factor >= root) break; if (root % factor != 0) continue; int quotient = root / factor; if (subResult.find(quotient) != subResult.end()) { subResult[root] += subResult[factor] * subResult[quotient]; } } } for (auto& entry : subResult) { result += entry.second; } return result % MOD; } };