Skip to content

Commit 42c5ffa

Browse files
committed
feat: 源¢寃쎌 6二쇱감 怨쇱�
1 parent 32f4893 commit 42c5ffa

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# 김경우
2+
---
3+
## 1. N으로 표현
4+
- 나의 풀이
5+
````javascript
6+
const DP = (N, number, callStack, dp) => {
7+
// callStafck 몇번째 호출인지 알려주는 변수
8+
callStack++;
9+
10+
// 만약 callStack이 4라면, 4번째 호출이라는 의미이고, 그때 만들 수 있는 수의 조합
11+
// 1+3, 2+2, 3+1
12+
// 여기서 중요한 점은 1+3과 3+1이 다른 것. (ex. 5/555 , 555/5)
13+
for (let i = 1; i < callStack; i++) {
14+
for (let x of dp[i]) {
15+
for (let y of dp[callStack - i]) {
16+
if(x + y > 0) dp[callStack].add(x + y);
17+
if(x - y > 0)dp[callStack].add(x - y);
18+
if(x * y > 0) dp[callStack].add(x * y);
19+
if (y !== 0) dp[callStack].add(Math.floor(x / y));
20+
}
21+
}
22+
}
23+
24+
// 여기는 숫자 이어 붙였을 때
25+
dp[callStack].add(Number(String(N).repeat(callStack)));
26+
27+
// 해당 callStack에서 number가 조합되었으면 callStack이 정답이니까 리턴.
28+
if (dp[callStack].has(number)) {
29+
return callStack;
30+
}
31+
32+
// 그게 아니면 아직 number를 못찾았으니까 -1 리턴.
33+
return -1;
34+
}
35+
36+
function solution(N, number) {
37+
if (N === number) return 1;
38+
39+
// 중복은 피하기 위해서 Set의 배열 생성
40+
const dp = Array.from({ length: 9 }, () => new Set());
41+
42+
// 8번 이상의 호출은 의미가 없으므로 반복문은 최대 8번 반복
43+
for (let i = 1; i <= 8; i++) {
44+
const answer = DP(N, number, i - 1, dp);
45+
if (answer !== -1) return answer;
46+
}
47+
48+
return -1;
49+
}
50+
````
51+
52+
- 학습내용
53+
````
54+
1. DP를 풀 때 떠올려야할 아이디어는 이전에 계산된 결과들을 사용하여 다음 결과물을 만들 수 있는지 생각하는 것.
55+
2. 대부분 DP문제는 dfs나 bfs로 풀 수 있을 것 같음.
56+
3. 중복된 계산을 계속 반복해야 한다면 DP를 사용.
57+
````
58+
---
59+
## 2. 정수 삼각형
60+
- 나의 풀이(DP)
61+
````javascript
62+
function solution(triangle) {
63+
const height = triangle.length;
64+
65+
// 7
66+
// 3 8
67+
// 8 1 0
68+
// 2 7 4 4
69+
// 4 5 2 6 5
70+
71+
// 삼각형의 높이 만큼 반복문 시행
72+
for(let i = 1; i < height; i++) {
73+
for(let j = 0; j < i + 1; j++) {
74+
if(j === 0) {
75+
// j가 0이라는 것은 삼각형의 각 레벨의 첫번째 인덱스라는 의미
76+
// 해당 위치 값은 이전 위치에서 왼쪽 아래로만 이동으로만 생성
77+
// 이동이 완료된 위치에 값을 누적
78+
triangle[i][j] = triangle[i][j] + triangle[i - 1][j];
79+
} else if (i === j) {
80+
// i와 j가 같다는 것은 삼각형의 각 레벨의 맨 끝에 있는 인덱스라는 의미
81+
// 해당 위치값은 이전 위치에서 오른쪽 아래로만 이동으로만 생성
82+
// 이동이 완료된 위치에 값을 누적
83+
triangle[i][j] = triangle[i][j] + triangle[i - 1][j - 1];
84+
} else {
85+
// 위의 상황들에 속하지 않으면 양쪽에서 값이 오는 상횡이고, 만들어진 값들 중에서 최대값을 선택해서 이동 후 위치에 값을 누적
86+
var max = triangle[i][j] + triangle[i - 1][j - 1];
87+
if(max < triangle[i][j] + triangle[i - 1][j])
88+
max = triangle[i][j] + triangle[i - 1][j];
89+
triangle[i][j] = max
90+
}
91+
}
92+
}
93+
94+
// 결국 triangle의 제일 하단부에는 만들어진 값의 배열이 존재
95+
// 거기서 최댓값 가져와
96+
return Math.max(...triangle[height-1]);
97+
}
98+
````
99+
<br/><br/>
100+
101+
- 나의 풀이(DFS)
102+
````javascript
103+
function solution(triangle) {
104+
const height = triangle.length;
105+
const temp = Array(height).fill(null).map((val, idx) => Array(idx + 1).fill(null));
106+
console.log(temp)
107+
108+
// 7
109+
// 3 8
110+
// 8 1 0
111+
// 2 7 4 4
112+
// 4 5 2 6 5
113+
114+
const dfs = (level, index) => {
115+
116+
// dfs의 재귀 호출에서 삼각형의 제일 하단부에 위치하게 되면 그 위치에 있는 값을 가져옴
117+
if (level === height - 1) {
118+
return triangle[level][index];
119+
}
120+
121+
// temp는 생성되고 나서 null로 채워져 있고, 이 null 값들은 dfs를 돌면서 숫자로 바뀔 것임.
122+
// 만약 현재 보고 있는 dfs의 level과 index에 있는 temp의 값이 null이 아니라는 것은 이미 값이 만들어서 채워졌다는 것.
123+
// 그럼 원래 있던 값을 리턴
124+
if (temp[level][index] !== null) {
125+
return temp[level][index];
126+
}
127+
128+
// left와 right로 들어면 level과 index의 자식들을 dfs로 재귀 호출
129+
const left = dfs(level + 1, index);
130+
const right = dfs(level + 1, index + 1);
131+
132+
// 현재 level과 index에 속하는 temp에는 이때의 triangle의 값과 이때의 temp의 자식들 중에서 최댓값을 더하도록 함.
133+
temp[level][index] = triangle[level][index] + Math.max(left, right);
134+
135+
// 그때의 값을 리턴
136+
return temp[level][index];
137+
}
138+
139+
// 맨 처음 시작하는 위치로 dfs 실행
140+
return dfs(0, 0);
141+
}
142+
````
143+
---
144+
## 3. 등굣길
145+
- 나의 풀이(DP)
146+
````javascript
147+
function solution(m, n, puddles) {
148+
149+
// 지도 생성성
150+
var map = Array.from({ length: n }, () => Array(m).fill(0));
151+
152+
// 시작점 설정
153+
map[0][0] = 1;
154+
155+
// 물 웅덩이는 -1로 해서 표시해놓기
156+
for(const element of puddles) {
157+
map[element[1] - 1][element[0] - 1] = -1;
158+
}
159+
160+
// dp 맵이 n x m 이니까 그만큼 이중반복으로 살펴보기
161+
for(let i = 0; i < n; i++) {
162+
for(let j = 0; j < m; j++) {
163+
// 만약 만난 곳이 물 웅덩이면 0으로 설정하고 패스
164+
// 물 웅덩이가 아니면 이전위치랑 현재위치 값 더함
165+
if(map[i][j] === -1) {
166+
map[i][j] = 0
167+
} else {
168+
if(i > 0) map[i][j] += map[i - 1][j];
169+
if(j > 0) map[i][j] += map[i][j - 1];
170+
map[i][j] %= 1000000007
171+
}
172+
}
173+
}
174+
175+
// 결국 map의 도착지점에는 경로의 합이 누적되었을겨.
176+
return map[n-1][m-1]
177+
}
178+
````
179+
180+
<br/><br/>
181+
182+
- 나의 풀이(BFS)
183+
```` javascript
184+
function solution(m, n, puddles) {
185+
// 맵 생성
186+
const map = Array.from({ length: n }, () => Array(m).fill(0));
187+
188+
// 물 웅덩이 표시
189+
for (const element of puddles) {
190+
map[element[1] - 1][element[0] - 1] = -1;
191+
}
192+
193+
// 시작점 설정
194+
map[0][0] = 1;
195+
196+
// BFS에 사용할 큐
197+
var queue = [[0,0]];
198+
199+
//BFS 시작
200+
while(queue.length !== 0) {
201+
const [x,y] = queue.shift();
202+
203+
// 아래로 가기
204+
var a = x + 1
205+
var b = y;
206+
207+
// 아래로 이동한 점이 물 웅덩이도 아니고 맵도 벗어난게 아니면 해당 점 enqueue
208+
if(a < n && b < m && map[a][b] !== -1) {
209+
if(map[a][b] === 0) {
210+
queue.push([a,b])
211+
}
212+
// 해당 점까지의 가는 방법의 수는 원래 자기가 가지고 있던 값에 이전 경로에서 들어온 값을 더함
213+
map[a][b] = (map[a][b] + map[x][y]) % 1000000007
214+
}
215+
216+
// 오른쪽으로 가기
217+
a = x;
218+
b = y + 1;
219+
220+
// 오른쪽으로 이동한 점이 물 웅덩이도 아니고 맵도 벗어난게 아니면 해당 점 enqueue
221+
if(a < n && b < m && map[a][b] !== -1) {
222+
if(map[a][b] === 0) {
223+
queue.push([a,b])
224+
}
225+
// 해당 점까지의 가는 방법의 수는 원래 자기가 가지고 있던 값에 이전 경로에서 들어온 값을 더함
226+
map[a][b] = (map[a][b] + map[x][y]) % 1000000007
227+
}
228+
}
229+
230+
return map[n-1][m-1]
231+
}
232+
````

0 commit comments

Comments
 (0)