diff --git a/best-time-to-buy-and-sell-stock/hwi-middle.cpp b/best-time-to-buy-and-sell-stock/hwi-middle.cpp new file mode 100644 index 0000000000..99916b5079 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/hwi-middle.cpp @@ -0,0 +1,15 @@ +class Solution { +public: + int maxProfit(vector& prices) { + int res = 0; + int minPrice = prices[0]; + int len = prices.size(); + for (int i = 0; i < len; ++i) + { + res = max(res, prices[i] - minPrice); // 수익 최대화: 지금까지 가장 쌌던 날에 사서 오늘 팔기 + minPrice = min(minPrice, prices[i]); // '지금까지 가장 쌌던 날' 업데이트 + } + + return res; + } +}; diff --git a/encode-and-decode-strings/hwi-middle.cpp b/encode-and-decode-strings/hwi-middle.cpp new file mode 100644 index 0000000000..e40f0db658 --- /dev/null +++ b/encode-and-decode-strings/hwi-middle.cpp @@ -0,0 +1,29 @@ +class Codec { +public: + + // Encodes a list of strings to a single string. + string encode(vector& strs) { + string str; + for(auto& s : strs) + { + str += s; + str.push_back(3); // 문제의 입력으로 오지 않는 값(ETX, End of Text)을 구분자로 사용 + } + + return str; + } + + // Decodes a single string to a list of strings. + vector decode(string s) { + vector v; + v.reserve(200); + string str_buf; + istringstream iss(s); + while (getline(iss, str_buf, (char)3)) + { + v.push_back(str_buf); + } + + return v; + } +}; diff --git a/group-anagrams/hwi-middle.cpp b/group-anagrams/hwi-middle.cpp new file mode 100644 index 0000000000..8731cde484 --- /dev/null +++ b/group-anagrams/hwi-middle.cpp @@ -0,0 +1,60 @@ +class Solution { +private: + // 단어별로 알파벳 개수를 세는 구조체 + struct chnum + { + int cnt[26]; + + chnum() + { + memset(cnt, 0, sizeof(int) * 26); + } + + bool operator==(const chnum& other) const + { + for (int i = 0; i < 26; ++i) + { + if (this->cnt[i] != other.cnt[i]) return false; + } + return true; + } + }; + +struct chnumHash + { + size_t operator()(const chnum& key) const + { + size_t seed = 5381; + for (int i = 0; i < 26; ++i) + { + seed = ((seed << 5) + seed) + key.cnt[i]; + } + return seed; + } + }; + +public: + vector> groupAnagrams(vector& strs) { + unordered_map, chnumHash> ns; // 알파벳 개수를 넣으면 알파벳 구성을 갖는 문자열 배열이 나옴 + for (auto& str : strs) + { + chnum n; + for (auto ch : str) + { + n.cnt[ch - 'a']++; // 알파벳 개수를 세고... + } + + ns[n].push_back(str); // 해시맵에 넣음 + } + + vector> v; + v.reserve(ns.size()); + + for (auto& p : ns) + { + v.push_back(move(p.second)); + } + + return v; + } +}; diff --git a/implement-trie-prefix-tree/hwi-middle.cpp b/implement-trie-prefix-tree/hwi-middle.cpp new file mode 100644 index 0000000000..15ee3233a9 --- /dev/null +++ b/implement-trie-prefix-tree/hwi-middle.cpp @@ -0,0 +1,68 @@ +class Trie +{ +public: + Trie() + { + mRoot = make_unique(); + } + + void insert(string word) + { + Node* curNode = mRoot.get(); + for (char c : word) + { + auto& child = curNode->children[c - 'a']; + if (child == nullptr) + { + child = make_unique(); + } + + curNode = child.get(); + } + + curNode->isWord = true; + } + + bool search(string word) + { + Node* curNode = mRoot.get(); + for (char c : word) + { + auto& child = curNode->children[c - 'a']; + if (child == nullptr) + { + return false; + } + + curNode = child.get(); + } + + return curNode->isWord; + } + + bool startsWith(string prefix) + { + Node* curNode = mRoot.get(); + for (char c : prefix) + { + auto& child = curNode->children[c - 'a']; + if (child == nullptr) + { + return false; + } + + curNode = child.get(); + } + + return true; + } + +private: + struct Node + { + bool isWord = false; // 이 노드가 단어의 끝인지 저장 + unique_ptr children[26]; // 자식 노드 저장 + }; + + unique_ptr mRoot; +}; diff --git a/word-break/hwi-middle.cpp b/word-break/hwi-middle.cpp new file mode 100644 index 0000000000..e9ab14d091 --- /dev/null +++ b/word-break/hwi-middle.cpp @@ -0,0 +1,46 @@ +class Solution { +public: + bool wordBreak(string s, vector& wordDict) { + this->s = s; + return solve(0, wordDict); + } + + // substr 시작 인덱스와 wordDict를 입력으로 받음 + bool solve(int start, vector& wordDict) + { + // 이미 계산한 적 있으면 메모이제이션으로 해결 + if (memo.contains(start)) + { + return memo[start]; + } + + // 베이스컨디션 -> 끝까지 도달했으면 true + if (start == s.size()) + { + return true; + } + + for (auto& str : wordDict) + { + // wordDict에 있는 단어들로 시작하는지 확인 + if (s.substr(start, str.size()) == str) + { + // 그리고 그 뒷 부분도 재귀를 통해 확인 + if (solve(start + str.size(), wordDict)) + { + // 뒷 부분까지 통과했으면 true + memo[start] = true; + return true; + } + } + } + + // 통과 못했으면 false + memo[start] = false; + return false; + } + +private: + string s; + unordered_map memo; // 메모이제이션 +};