380. Insert Delete GetRandom O(1)

  • O(1)으둜 mapping을 ꡬ성함과 λ™μ‹œμ— random accessλ₯Ό μˆ˜ν–‰ν•  수 μžˆλŠ” 방법에 λŒ€ν•΄μ„œ λ¬»λŠ” λ¬Έμ œμ΄λ‹€.
    • 두 κ°€μ§€ 자료ꡬ쑰λ₯Ό μ‘°ν•©ν•˜μ—¬ ν•΄κ²°ν•˜λŠ” λ¬Έμ œμ΄λ‹€.
  • μ²˜μŒμ—λŠ” 직접 Nodeλ₯Ό κ΅¬ν˜„ν•΄μ„œ hash mapκ³Ό linked listλ₯Ό ν™œμš©ν•΄μ„œ ν’€μ—ˆμ—ˆλ‹€.
    • ν•˜μ§€λ§Œ getRandom κ΅¬ν˜„μ—μ„œ linked listλ₯Ό random access ν•  μˆ˜κ°€ μ—†μ–΄μ„œ λ¬Έμ œκ°€ λ˜μ—ˆλ‹€.
  • μƒκ°ν•΄λ³΄λ‹ˆ insert/deleteλ₯Ό O(1)에 ν•˜λ €λ©΄ unordered_map 을 μ“°λ©΄ λ˜λŠ” κ±°μ˜€λ‹€.
    • λ¬Έμ œλŠ” random access도 같이 μ œκ³΅ν•΄μ•Ό λ˜λ―€λ‘œ μ‹€μ œ 값은 vector에 μœ„μΉ˜ν•΄μ•Ό ν•œλ‹€λŠ” λ¬Έμ œκ°€ μžˆμ—ˆλ‹€.
    • κ²°κ΅­ λ‹€λ₯Έ μ‚¬λžŒμ˜ μ†”λ£¨μ…˜μ„ μ°Έκ³ ν–ˆλŠ”λ° unordered_mapμ—λŠ” vector μƒμ˜ μœ„μΉ˜λ₯Ό μ €μž₯ν•˜κ³  vectorμ—λŠ” μ‹€μ œ 값을 μ €μž₯ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν•΄κ²°ν–ˆλ‹€.
    • μ‚­μ œν•  λ•ŒλŠ” (1) μ‚­μ œν•˜λŠ” κ°’κ³Ό vector의 λ§ˆμ§€λ§‰ 값을 swapν•˜κ³  (2)vectorμ—μ„œ λ§ˆμ§€λ§‰ ν•­λͺ©μ„ 제거 vector::pop_back() (3) unordered_mapμ—μ„œ swap된 κ°’μ˜ μœ„μΉ˜λ₯Ό updateν•˜λŠ” 방식을 μ·¨ν•œλ‹€.
class RandomizedSet { public: RandomizedSet() : positions(), values() { } bool insert(int val) { auto itr = positions.find(val); if (itr != positions.end()) return false; int pos = values.size(); values.push_back(val); positions[val] = pos; return true; } bool remove(int val) { auto itr = positions.find(val); if (itr == positions.end()) return false; int pos = itr->second; int lastVal = values[values.size() - 1]; // swap last element to removed position values[pos] = lastVal; positions[lastVal] = pos; // remove element & pos values.pop_back(); positions.erase(itr); return true; } int getRandom() { int index = rand() % values.size(); return values[index]; } private: unordered_map<int, int> positions; vector<int> values; };