Skip to content

Commit d2910bf

Browse files
authored
Merge pull request DaleStudy#2528 from hwi-middle/main
[hwi-middle] WEEK 06 solutions
2 parents 4b77d54 + dd2cee8 commit d2910bf

File tree

5 files changed

+253
-0
lines changed

5 files changed

+253
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution {
2+
public:
3+
int maxArea(vector<int>& height) {
4+
int l = 0;
5+
int r = height.size() - 1;
6+
7+
int area = 0;
8+
9+
// 투 포인터로 접근
10+
while (l < r)
11+
{
12+
// 너비(물 저장량)를 구하고 최댓값 업데이트
13+
area = max(area, (r - l) * min(height[r], height[l]));
14+
15+
// 높이가 낮은 쪽의 커서를 이동
16+
// -> 높은 쪽의 커서를 움직이면 무조건 손해
17+
// -> 너비는 줄어들고 높이까지 줄어드니까
18+
if (height[l] < height[r])
19+
{
20+
l++;
21+
}
22+
else
23+
{
24+
r--;
25+
}
26+
}
27+
28+
return area;
29+
}
30+
};
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// 풀이 접근: Trie로 해결
2+
3+
class WordDictionary {
4+
public:
5+
WordDictionary() {
6+
mRoot = make_unique<Node>(); // RAII를 위해 스마트 포인터 사용
7+
}
8+
9+
void addWord(string word) {
10+
Node* curNode = mRoot.get();
11+
for (char c : word)
12+
{
13+
auto& child = curNode->children[c - 'a'];
14+
if (child == nullptr)
15+
{
16+
child = make_unique<Node>();
17+
}
18+
19+
curNode = child.get();
20+
}
21+
22+
curNode->isWord = true;
23+
}
24+
25+
bool search(string word) {
26+
return search_impl(word, mRoot.get());
27+
}
28+
29+
private:
30+
struct Node
31+
{
32+
bool isWord = false;
33+
unique_ptr<Node> children[26];
34+
};
35+
36+
unique_ptr<Node> mRoot;
37+
38+
// 복사 없는 substr을 위해 std::string_view 활용
39+
bool search_impl(string_view word, Node* root)
40+
{
41+
Node* curNode = root;
42+
for (int i = 0; i < word.size(); ++i)
43+
{
44+
char c = word[i];
45+
if (c == '.') // '.'은 와일드 카드이므로 자식 노드를 모두 순회하며 시도
46+
{
47+
for (auto& p : curNode->children)
48+
{
49+
if (p != nullptr && search_impl(word.substr(i + 1), p.get()))
50+
{
51+
return true;
52+
}
53+
}
54+
55+
return false;
56+
}
57+
else
58+
{
59+
auto& child = curNode->children[c - 'a'];
60+
if (child == nullptr)
61+
{
62+
return false;
63+
}
64+
65+
curNode = child.get();
66+
}
67+
}
68+
69+
return curNode->isWord;
70+
}
71+
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// O(n^2) 풀이
2+
class Solution {
3+
public:
4+
int lengthOfLIS(vector<int>& nums) {
5+
int n = nums.size();
6+
vector<int> d(n); // 점화식: d[i] = a[i]를 마지막으로 하는 LIS 길이
7+
8+
for (int i = 0; i < n; ++i)
9+
{
10+
d[i] = 1; // 최솟값은 1
11+
for (int j = 0; j < i; ++j)
12+
{
13+
// 증가하는 부분수열이고, 기존에 구한 길이보다 길면 업데이트
14+
if (nums[j] < nums[i] && d[j] + 1 > d[i])
15+
{
16+
d[i] = d[j] + 1;
17+
}
18+
}
19+
}
20+
21+
// d의 최댓값 반환
22+
return *max_element(d.begin(), d.end());
23+
}
24+
};
25+
26+
// O(n log n) 풀이
27+
class Solution {
28+
public:
29+
int lengthOfLIS(vector<int>& nums) {
30+
int n = nums.size();
31+
vector<int> d; // d[i] = 길이가 i + 1인 LIS의 가장 작은 마지막 값
32+
33+
for (int i = 0; i < n; ++i)
34+
{
35+
auto it = lower_bound(d.begin(), d.end(), nums[i]);
36+
if (it == d.end()) // nums[i]가 d의 모든 원소보다 큰 경우
37+
{
38+
d.push_back(nums[i]);
39+
}
40+
else // nums[i]의 자리를 찾은 경우
41+
{
42+
*it = nums[i]; // 그냥 대체하는게 이득임 -> 길이는 유지됐고, 더 이어붙일 수 있는 수의 범위는 늘어나므로
43+
}
44+
}
45+
46+
return d.size();
47+
}
48+
};

spiral-matrix/hwi-middle.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
class Solution {
2+
public:
3+
vector<int> spiralOrder(vector<vector<int>>& matrix) {
4+
int m = matrix.size();
5+
int n = matrix[0].size();
6+
7+
int top = 0;
8+
int bottom = m - 1;
9+
int left = 0;
10+
int right = n - 1;
11+
12+
vector<int> v;
13+
v.reserve(m * n);
14+
15+
while(top <= bottom && left <= right)
16+
{
17+
// 오른쪽으로 이동
18+
for (int i = left; i <= right; ++i)
19+
{
20+
v.push_back(matrix[top][i]);
21+
}
22+
top++;
23+
24+
// 아래쪽으로 이동
25+
for (int i = top; i <= bottom; ++i)
26+
{
27+
v.push_back(matrix[i][right]);
28+
}
29+
right--;
30+
31+
// 왼쪽으로 이동
32+
if (top <= bottom)
33+
{
34+
for (int i = right; i >= left; --i)
35+
{
36+
v.push_back(matrix[bottom][i]);
37+
}
38+
bottom--;
39+
}
40+
41+
// 위쪽으로 이동
42+
if (left <= right)
43+
{
44+
for (int i = bottom; i >= top; --i)
45+
{
46+
v.push_back(matrix[i][left]);
47+
}
48+
left++;
49+
}
50+
}
51+
52+
return v;
53+
}
54+
};

valid-parentheses/hwi-middle.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
class Solution {
2+
public:
3+
bool isValid(string s) {
4+
stack<char> st; // 여는 괄호를 저장할 스택
5+
6+
for (char ch : s)
7+
{
8+
if (isOpening(ch)) // 여는 괄호라면 스택에 push
9+
{
10+
st.push(ch);
11+
continue;
12+
}
13+
14+
if (st.empty()) // 스택이 비었는데 닫는 괄호면 invalid
15+
{
16+
return false;
17+
}
18+
19+
char t = st.top();
20+
st.pop();
21+
22+
// 괄호 쌍이 맞으면 계속 진행
23+
if ((ch == ')' && t == '(')
24+
|| (ch == ']' && t == '[')
25+
|| (ch == '}' && t == '{'))
26+
{
27+
continue;
28+
}
29+
30+
// 괄호 쌍이 맞지 않으면 invalid
31+
return false;
32+
}
33+
34+
return st.empty();
35+
}
36+
37+
private:
38+
bool isOpening(char c)
39+
{
40+
switch(c)
41+
{
42+
case '(':
43+
case '[':
44+
case '{':
45+
return true;
46+
}
47+
48+
return false;
49+
}
50+
};

0 commit comments

Comments
 (0)