341. Flatten Nested List Iterator

  • ์žฌ๊ท€ ๊ตฌ์กฐ๋กœ ๊ตฌํ˜„๋œ ์ˆซ์ž ๋ชฉ๋ก์„ ์ˆœํšŒํ•˜๋Š” iterator๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฌธ์ œ.
  • ํ˜„์žฌ list์™€ ์œ„์น˜๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด Entry ๋ฅผ ๋งŒ๋“ค๊ณ  stack์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์ค‘์ฒฉ๋œ list์˜ ์œ„์น˜ ์ •๋ณด๋ฅผ ํ‘œํ˜„ํ•œ๋‹ค.
  • List์—์„œ ๋‹ค์Œ ์ˆซ์ž ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” Entry๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜ ensureNext๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.
    • Stack์˜ ๋งˆ์ง€๋ง‰ Entry๋ฅผ ๊ธฐ์ค€์œผ๋กœ
      • iterator๊ฐ€ ํ˜„์žฌ list์˜ ๋งˆ์ง€๋ง‰์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒฝ์šฐ stack์—์„œ ์ œ๊ฑฐํ•œ๋‹ค.
      • iterator๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•ญ๋ชฉ์ด ์ˆซ์ž์ธ ๊ฒฝ์šฐ ํ˜„์žฌ Entry๋ฅผ ๋Œ๋ ค์ค€๋‹ค.
      • iterator๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•ญ๋ชฉ์ด ๋ชฉ๋ก์ธ ๊ฒฝ์šฐ
        • ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•ด๋‘”๋‹ค nextList
        • iterator๋ฅผ ํ•˜๋‚˜ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค
        • Stack์— nextList์— ๋Œ€ํ•œ entry๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • hasNext์—์„œ๋Š” ensureNext์—์„œ ๋Œ๋ ค์ฃผ๋Š” entry๊ฐ€ ์กด์žฌ (not null)ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  • next์—์„œ๋Š” ensureNext์—์„œ ๋Œ๋ ค์ฃผ๋Š” entry์˜ ๊ฐ’์„ ์ฝ๊ณ  entry์˜ iterator๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
/** * // This is the interface that allows for creating nested lists. * // You should not implement it, or speculate about its implementation * class NestedInteger { * public: * // Return true if this NestedInteger holds a single integer, rather than a nested list. * bool isInteger() const; * * // Return the single integer that this NestedInteger holds, if it holds a single integer * // The result is undefined if this NestedInteger holds a nested list * int getInteger() const; * * // Return the nested list that this NestedInteger holds, if it holds a nested list * // The result is undefined if this NestedInteger holds a single integer * const vector<NestedInteger> &getList() const; * }; */ class NestedIterator { public: using ListPtr = vector<NestedInteger>*; using ListItr = vector<NestedInteger>::iterator; using Entry = pair<ListPtr, ListItr>; NestedIterator(vector<NestedInteger> &nestedList) { entries.emplace_back(&nestedList, nestedList.begin()); } int next() { auto* entry = ensureNext(); if (entry == nullptr) return -1; int result = entry->second->getInteger(); ++(entry->second); return result; } bool hasNext() { return ensureNext() != nullptr; } Entry* ensureNext() { while (!entries.empty()) { auto& entry = entries.back(); if (entry.second == entry.first->end()) { entries.pop_back(); continue; } if (entry.second->isInteger()) return &entry; auto& nextList = entry.second->getList(); ++entry.second; entries.emplace_back(&nextList, nextList.begin()); } return nullptr; } private: vector<Entry> entries; }; /** * Your NestedIterator object will be instantiated and called as such: * NestedIterator i(nestedList); * while (i.hasNext()) cout << i.next(); */