Skip to content

Commit ce9ec5d

Browse files
authored
Merge pull request #462 from wogha95/main
[재호] WEEK 06 Solutions
2 parents cfc0c46 + e8f521c commit ce9ec5d

File tree

5 files changed

+330
-0
lines changed

5 files changed

+330
-0
lines changed

container-with-most-water/wogha95.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* TC: O(H)
3+
* SC: O(1)
4+
* H: height.length
5+
*/
6+
7+
/**
8+
* @param {number[]} height
9+
* @return {number}
10+
*/
11+
var maxArea = function (height) {
12+
let maximumWater = 0;
13+
let left = 0;
14+
let right = height.length - 1;
15+
16+
// 1. 투포인터를 이용하여 양끝에서 모입니다.
17+
while (left < right) {
18+
// 2. 최대 너비값을 갱신해주고
19+
const h = Math.min(height[left], height[right]);
20+
const w = right - left;
21+
22+
maximumWater = Math.max(maximumWater, w * h);
23+
24+
// 3. 왼쪽과 오른쪽 높이 중 더 낮은 쪽의 pointer를 옮깁니다.
25+
if (height[left] < height[right]) {
26+
left += 1;
27+
} else {
28+
right -= 1;
29+
}
30+
}
31+
32+
return maximumWater;
33+
};
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
function Node() {
2+
// 단어의 끝을 의미 + 무슨 단어인지 저장
3+
this.value = null;
4+
// 단어의 다음 문자로 연결되어 있는 노드맵
5+
this.wordGraph = new Map();
6+
}
7+
8+
var WordDictionary = function () {
9+
this.wordGraph = new Map();
10+
};
11+
12+
/**
13+
* TC: O(N)
14+
* SC: O(N)
15+
*/
16+
17+
/**
18+
* @param {string} word
19+
* @return {void}
20+
*/
21+
WordDictionary.prototype.addWord = function (word) {
22+
let pointer = this;
23+
for (const w of word) {
24+
if (!pointer.wordGraph.has(w)) {
25+
pointer.wordGraph.set(w, new Node());
26+
}
27+
pointer = pointer.wordGraph.get(w);
28+
}
29+
pointer.value = word;
30+
};
31+
32+
/**
33+
* TC: O(D^W)
34+
* SC: O(D * W)
35+
*
36+
* W: word.length, D: count of Dictionary.wordGraph keys
37+
*
38+
* 풀이: Trie 자료구조 + bfs탐색
39+
*/
40+
41+
/**
42+
* @param {string} word
43+
* @return {boolean}
44+
*/
45+
WordDictionary.prototype.search = function (word) {
46+
const queue = [{ pointer: this, index: 0 }];
47+
48+
// 1. BFS 탐색 방법 이용
49+
while (queue.length > 0) {
50+
const { pointer, index } = queue.shift();
51+
52+
// 2. 찾고자하는 단어의 끝에 도달했으면 해당 단어가 있는지 확인한다.
53+
if (index === word.length) {
54+
if (pointer.value !== null) {
55+
return true;
56+
}
57+
continue;
58+
}
59+
60+
if (word[index] === ".") {
61+
// 3. 찾고자하는 단어의 문자가 '.'인 경우, 현재 graph에서 이어진 문자를 모두 탐색(queue에 추가)
62+
for (const [key, node] of pointer.wordGraph) {
63+
queue.push({ pointer: node, index: index + 1 });
64+
}
65+
} else if (pointer.wordGraph.has(word[index])) {
66+
// 4. 찾고자하는 단어의 문자가 graph에 있는 경우 탐색(queue에 추가)
67+
queue.push({
68+
pointer: pointer.wordGraph.get(word[index]),
69+
index: index + 1,
70+
});
71+
}
72+
}
73+
74+
// 5. 더이상 탐색할 것이 없다면 해당 단어 없음으로 판단
75+
return false;
76+
};
77+
78+
/**
79+
* Your WordDictionary object will be instantiated and called as such:
80+
* var obj = new WordDictionary()
81+
* obj.addWord(word)
82+
* var param_2 = obj.search(word)
83+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* TC: O(N^2)
3+
* SC: O(N)
4+
* N: nums.length
5+
*/
6+
7+
/**
8+
* @param {number[]} nums
9+
* @return {number}
10+
*/
11+
var lengthOfLIS = function (nums) {
12+
// 각자 스스로는 최소 1의 lengthOfLIS를 가짐
13+
const longestLength = new Array(nums.length).fill(1);
14+
let result = 1;
15+
16+
// nums배열의 right까지 원소들 중 lengthOfLIS를 저장
17+
for (let right = 1; right < nums.length; right++) {
18+
for (let left = 0; left < right; left++) {
19+
if (nums[left] < nums[right]) {
20+
longestLength[right] = Math.max(
21+
longestLength[right],
22+
longestLength[left] + 1
23+
);
24+
result = Math.max(result, longestLength[right]);
25+
}
26+
}
27+
}
28+
29+
return result;
30+
};

spiral-matrix/wogha95.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/**
2+
* 2차 풀이: 기존 matrix 변경 없도록 개선
3+
*
4+
* TC: O(ROW * COLUMN)
5+
* matrix 전체 순회 1회
6+
*
7+
* SC: O(ROW * COLUMN)
8+
* 정답 제출을 위한 result 공간복잡도
9+
*/
10+
11+
/**
12+
* @param {number[][]} matrix
13+
* @return {number[]}
14+
*/
15+
var spiralOrder = function (matrix) {
16+
const ROW = matrix.length;
17+
const COLUMN = matrix[0].length;
18+
// 1. 상하좌우 시작끝 index를 저장함
19+
const boundary = {
20+
top: 0,
21+
bottom: ROW - 1,
22+
left: 0,
23+
right: COLUMN - 1,
24+
};
25+
const result = [];
26+
27+
while (result.length < ROW * COLUMN) {
28+
// 2. 오른쪽으로 순회
29+
for (let column = boundary.left; column <= boundary.right; column++) {
30+
result.push(matrix[boundary.top][column]);
31+
}
32+
boundary.top += 1;
33+
34+
// 3. 아래로 순회
35+
for (let row = boundary.top; row <= boundary.bottom; row++) {
36+
result.push(matrix[row][boundary.right]);
37+
}
38+
boundary.right -= 1;
39+
40+
// 4. 모두 순회했는데 왔던길 되돌아가는 경우를 막기위해 중간 조건문 추가
41+
if (result.length === ROW * COLUMN) {
42+
break;
43+
}
44+
45+
// 5. 왼쪽으로 순회
46+
for (let column = boundary.right; column >= boundary.left; column--) {
47+
result.push(matrix[boundary.bottom][column]);
48+
}
49+
boundary.bottom -= 1;
50+
51+
// 6. 위쪽으로 순회
52+
for (let row = boundary.bottom; row >= boundary.top; row--) {
53+
result.push(matrix[row][boundary.left]);
54+
}
55+
boundary.left += 1;
56+
}
57+
58+
return result;
59+
};
60+
61+
/**
62+
* 1차 풀이
63+
*
64+
* TC: O(ROW * COLUMN)
65+
* matrix 전체 순회 1회
66+
*
67+
* SC: O(ROW * COLUMN)
68+
* 정답 제출을 위한 result 공간복잡도
69+
*/
70+
71+
/**
72+
* @param {number[][]} matrix
73+
* @return {number[]}
74+
*/
75+
var spiralOrder = function (matrix) {
76+
const ROW = matrix.length;
77+
const COLUMN = matrix[0].length;
78+
// 우하좌상 순서
79+
const DIRECTION = [
80+
{
81+
row: 0,
82+
column: 1,
83+
},
84+
{
85+
row: 1,
86+
column: 0,
87+
},
88+
{
89+
row: 0,
90+
column: -1,
91+
},
92+
{
93+
row: -1,
94+
column: 0,
95+
},
96+
];
97+
98+
// 1. 첫 시작점 방문표시
99+
const result = [matrix[0][0]];
100+
matrix[0][0] = "#";
101+
102+
let current = {
103+
row: 0,
104+
column: 0,
105+
};
106+
let directionIndex = 0;
107+
108+
// 2. 총 갯수만큼 채워질때까지 순회
109+
while (result.length < ROW * COLUMN) {
110+
const next = {
111+
row: current.row + DIRECTION[directionIndex].row,
112+
column: current.column + DIRECTION[directionIndex].column,
113+
};
114+
// 3. 다음 순회할 곳이 유효한 좌표인지 방문한 곳인지 확인
115+
if (
116+
!isValidPosition(next.row, next.column) ||
117+
matrix[next.row][next.column] === "#"
118+
) {
119+
// 4. 방향 전환
120+
directionIndex = (directionIndex + 1) % 4;
121+
} else {
122+
// 5. 방문 표시 후 다음 좌표로 이동
123+
result.push(matrix[next.row][next.column]);
124+
matrix[next.row][next.column] = "#";
125+
current = next;
126+
}
127+
}
128+
129+
return result;
130+
131+
function isValidPosition(row, column) {
132+
if (row < 0 || ROW <= row) {
133+
return false;
134+
}
135+
if (column < 0 || COLUMN <= column) {
136+
return false;
137+
}
138+
return true;
139+
}
140+
};

valid-parentheses/wogha95.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* TC: O(S)
3+
* s 매개변수의 길이만큼 순회 1번
4+
*
5+
* SC: O(S)
6+
* 최악의 경우 S의 길이만큼 stack 배열에 모두 push 할 수 있기 때문에
7+
*
8+
* S: s.length
9+
*/
10+
11+
/**
12+
* @param {string} s
13+
* @return {boolean}
14+
*/
15+
var isValid = function (s) {
16+
const map = {
17+
"(": ")",
18+
"{": "}",
19+
"[": "]",
20+
};
21+
const stack = [];
22+
23+
// 1. s의 길이만큼 순회를 하면서
24+
for (const char of s) {
25+
// 2. 열린 괄호라면 stack에 짝지어진 닫힌 괄호를 저장
26+
// 3. 닫힌 괄호라면 stack에서 꺼낸 것과 동일한지 확인
27+
switch (char) {
28+
case "(":
29+
case "{":
30+
case "[":
31+
stack.push(map[char]);
32+
break;
33+
case "}":
34+
case ")":
35+
case "]":
36+
if (stack.pop() !== char) {
37+
return false;
38+
}
39+
}
40+
}
41+
42+
// 4. 남은 괄호가 없는지 확인
43+
return stack.length === 0;
44+
};

0 commit comments

Comments
 (0)