diff --git a/container-with-most-water/sungjinwi.cpp b/container-with-most-water/sungjinwi.cpp new file mode 100644 index 000000000..97244f1e4 --- /dev/null +++ b/container-with-most-water/sungjinwi.cpp @@ -0,0 +1,32 @@ +/* + 풀이 : + 최대 넓이는 양 끝 기둥 길이 중 짧은 쪽을 기준으로 정해진다 + 양 끝에서 기둥을 시작하고 둘 중 짧은 쪽을 안쪽으로 이동하면서 최대 넓이를 찾는다 + + height의 개수 : N + + TC : O(N) + + SC : O(1) +*/ + +class Solution { + public: + int maxArea(vector& height) { + int left = 0; + int right = height.size() - 1; + int max_area = 0; + + while (left < right) + { + int cur_area = (right - left) * min(height[left], height[right]); + if (cur_area > max_area) + max_area = cur_area; + if (height[left] <= height[right]) + left++; + else + right--; + } + return max_area; + } + }; diff --git a/design-add-and-search-words-data-structure/sungjinwi.cpp b/design-add-and-search-words-data-structure/sungjinwi.cpp new file mode 100644 index 000000000..ca80b82ac --- /dev/null +++ b/design-add-and-search-words-data-structure/sungjinwi.cpp @@ -0,0 +1,87 @@ +/* + 풀이 : + Trie를 활용해서 단어를 저장한다 + 글자마다 이어지는 다음 글자에 대한 children[26](알파벳 소문자 개수 26개)를 가지고 현재 글자에서 끝나는지 여부(isEnd)를 가진다 + + addWord는 한글자씩 node에 없으면 추가하고 다음 글자의 노드로 이동하며 + word에 대한 반복을 마친 뒤 마지막 node의 isEnd를 1로 바꿈 + + search는 한글자씩 다음 노드로 이동하며 word의 끝에 다다랐을 떄 isEnd가 1인지 return + dfs를 활용하여 '.'이 나올 경우 알파벳 26개 모두에 대해 다음 글자부터 시작하는 dfs를 호출 + + word의 길이 : W + + TC : + addWord : O(W) + word 길이에 비례하여 반복문 + + search : O(26^W) + 최악의 경우 word길이 만큼 '.'이 있으면 하나하나 마다 26번의 재귀호출이 있다 + + SC : + addWord : O(W) + TrieNode 개수는 word길이에 비례 + + search : O(W) + 재귀 호출스택은 word 길이에 비례 +*/ + +class WordDictionary { + private: + struct TrieNode { + int isEnd = 0; + TrieNode* children[26] = {}; + }; + TrieNode* root; + + public: + WordDictionary() { + this->root = new TrieNode(); + } + + void addWord(string word) { + TrieNode* node = root; + for (auto& c : word) + { + int idx = c - 'a'; + if (!node->children[idx]) + node->children[idx] = new TrieNode(); + node = node->children[idx]; + } + node->isEnd = 1; + } + + bool search(string word) { + return dfs(word, this->root); + } + + bool dfs(string word, TrieNode* node) { + if (word.empty()) + return node->isEnd; + + for (int i = 0; i < word.size(); i++) + { + if (word[i] == '.') + { + for (int j=0; j < 26; j++) + { + if (node->children[j] && this->dfs(word.substr(i + 1), node->children[j])) + return true; + } + return false; + } + int idx = word[i] - 'a'; + if (!node->children[idx]) + return false; + node = node->children[idx]; + } + return node->isEnd; + } + }; + + /** + * Your WordDictionary object will be instantiated and called as such: + * WordDictionary* obj = new WordDictionary(); + * obj->addWord(word); + * bool param_2 = obj->search(word); + */ diff --git a/longest-increasing-subsequence/sungjinwi.cpp b/longest-increasing-subsequence/sungjinwi.cpp new file mode 100644 index 000000000..1439d62e2 --- /dev/null +++ b/longest-increasing-subsequence/sungjinwi.cpp @@ -0,0 +1,33 @@ +/* + nums와 길이가 같은 dp배열을 만들고 1로 초기화한다 + dp[i]의 값은 nums[i]으로 끝나는 LIS의 길이 + i 이후의 j에 대해 nums[j] > nums[i]일 경우 nums[j]를 nums[i]로 끝나는 LIS에 붙일 수 있으므로 + dp[j]와 dp[i + 1]을 비교해 큰 값으로 업데이트 + + nums의 길이 : N + + TC : O(N^2) + 반복문 내부의 반복문 + + SC : O(N) + dp의 길이는 nums길이에 비례 +*/ + +class Solution { + public: + int lengthOfLIS(vector& nums) { + vector dp(nums.size(), 1); + int max_len = 1; + + for (int i = 0; i < nums.size(); i++) + for (int j = i + 1; j < nums.size(); j++) + { + if (nums[j] > nums[i]) + { + dp[j] = max(dp[i] + 1, dp[j]); + max_len = max(dp[j], max_len); + } + } + return max_len; + } + }; diff --git a/spiral-matrix/sungjinwi.cpp b/spiral-matrix/sungjinwi.cpp new file mode 100644 index 000000000..bceaf694e --- /dev/null +++ b/spiral-matrix/sungjinwi.cpp @@ -0,0 +1,46 @@ +/* + 풀이 : + 상하좌우 범위지정해서 이동하는 것이 아니라 n_rows, n_cols 길이만큼 이동으로 풀이 + col 방향으로 움직이면 이동할 row 감소, row 방향 움직이면 n_cols 1 감소 + row, col 한번씩 이동하면 direction *= -1로 방향을 바꿔준다 + + matrix 크기 : M * N + + TC : O(M * N) + matrix 전체 순환 + + SC : O(1) + 리턴할 ans 제외하면 추가 메모리 사용은 상수 개수의 변수 +*/ + +class Solution { + public: + vector spiralOrder(vector>& matrix) { + int n_rows = matrix.size(); + int n_cols = matrix[0].size(); + vector ans; + + int row = 0, col = -1; + int direction = 1; + + while (n_rows > 0 && n_cols > 0) + { + for (int i = 0; i < n_cols; i++) + { + col += direction; + ans.push_back(matrix[row][col]); + } + n_rows--; + + for (int i = 0; i < n_rows; i++) + { + row += direction; + ans.push_back(matrix[row][col]); + } + n_cols--; + + direction *= -1; + } + return ans; + } + }; diff --git a/valid-parentheses/sungjinwi.cpp b/valid-parentheses/sungjinwi.cpp new file mode 100644 index 000000000..e5370d4dd --- /dev/null +++ b/valid-parentheses/sungjinwi.cpp @@ -0,0 +1,50 @@ +/* + 풀이 : + stack을 이용해서 괄호를 넣고 뺸다. + 닫는 괄호 ),],}를 만났을 때 가장 위의 괄호가 대응하는 괄호면 제거하고 비어있거나 맞지 않는 괄호면 return false + string을 모두 순회했을 떄 stack이 비어있지 않으면 return false + + s의 길이 N + + TC : O(N) + s에 대해 반복 1회 + + SC : O(N) + 최악의 경우 stack 크기는 s의 길이에 비례 +*/ + +class Solution { + public: + bool isValid(string s) { + stack st; + + for (auto& c : s) + { + if (c == ')') + { + if (st.empty() || st.top() != '(') + return false; + st.pop(); + } + if (c == '}') + { + if (st.empty() || st.top() != '{') + return false; + st.pop(); + } + if (c == ']') + { + if (st.empty() || st.top() != '[') + return false; + st.pop(); + } + else + st.push(); + } + + if (!st.empty()) + return false; + else + return true; + } + };