Skip to content

[sungjinwi] Week 06 solution #1447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions container-with-most-water/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
풀이 :
최대 넓이는 양 끝 기둥 길이 중 짧은 쪽을 기준으로 정해진다
양 끝에서 기둥을 시작하고 둘 중 짧은 쪽을 안쪽으로 이동하면서 최대 넓이를 찾는다

height의 개수 : N

TC : O(N)

SC : O(1)
*/

class Solution {
public:
int maxArea(vector<int>& 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;
}
};
87 changes: 87 additions & 0 deletions design-add-and-search-words-data-structure/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -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);
*/
33 changes: 33 additions & 0 deletions longest-increasing-subsequence/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -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<int>& nums) {
vector<int> 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;
}
};
46 changes: 46 additions & 0 deletions spiral-matrix/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -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<int> spiralOrder(vector<vector<int>>& matrix) {
int n_rows = matrix.size();
int n_cols = matrix[0].size();
vector<int> 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;
}
};
50 changes: 50 additions & 0 deletions valid-parentheses/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -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<char> 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;
}
};