Skip to content

Commit 2308fe0

Browse files
author
jinvicky
committed
best time to buy and sell stock solution and 4 week solution comment added
1 parent 2b1cf5a commit 2308fe0

File tree

3 files changed

+87
-23
lines changed

3 files changed

+87
-23
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 int maxProfit(int[] prices) {
3+
/**
4+
max라는 메모이제이션 변수를 int로 선언한다.
5+
dp로 모든 경우의 수를 고려할 것이다.
6+
7+
주식의 최소가격을 담은 변수를 int로 선언한다. 맨 처음에 prices[0] 값이 되면 좋겠다.
8+
9+
10+
*/
11+
int max = 0;
12+
int minStock = prices[0];
13+
14+
for (int i = 1; i < prices.length; i++) {
15+
/**
16+
현재 주식은 팔 때의 주식 가격을 나타낸다.
17+
max에는 현재 주식 가격 - 현재 최소 주식 가격의 값을 저장한다. (abs 금지)
18+
만약 현재 주식의 가격이 현재 최소 주식 가격보다 크다면
19+
현재 최소 주식의 가격으로 업데이트한다.
20+
*/
21+
int prc = prices[i];
22+
max = Math.max(max, prc - minStock);
23+
24+
if (minStock > prc) {
25+
minStock = prc;
26+
}
27+
}
28+
return max;
29+
}
30+
}

coin-change/jinvicky.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
import java.util.Arrays;
22

3+
4+
// 왜 greedy가 아닐까? amount가 7이라고 가정했을 때 greedy라면 [1,3,4,5]에서 5를 우선시해서 5+1+1 총 3개를 사용할 것이지만,
5+
// 실제 정답은 3+4 로 총 2개가 된다. 그렇기에 단순히 욕심쟁이로 최댓값, 최솟값으로 접근하는 방식은 적합하지 않다.
6+
// greedy가 아니라면 보통 DP로 풀이한다.
7+
// DP의 기초인 1. Climbing Stairs 2. Best Time to Buy and Sell Stock 3. House Robber를 선행으로 풀고 접근했다.
8+
// DP의 기본은 i-1, i-2식으로 기존 값을 재사용하는 메모이제이션인데 나는 bottom-up으로 모든 dp를 풀이하려고 노력한다. (일관성)
9+
// DP는 값을 비교하기 위해서 Math.min(), Math.max()를 많이 사용하기에 초기값을 Integer.MAX_VALUE, Integer.MIN_VALUE로 염두했다.
10+
311
class Solution {
412
public int coinChange(int[] coins, int amount) {
5-
int max=amount+1;
6-
int [] dp=new int[amount+1];
7-
Arrays.fill(dp,max);
8-
dp[0]=0;
9-
for(int coin:coins){
10-
for(int j=coin;j<=amount;j++){ // coin부터 시작해서 일반 루프보다 성능 향상
11-
dp[j]=Math.min(dp[j],dp[j-coin]+1);
13+
int max = amount + 1; // 값 미표현이라면 Integer.MAX_VALUE가 더 직관적이지 않나? -> testcase에서 음수값 나와서 실패함
14+
int[] dp = new int[amount + 1]; // 목표인 amount를 위한 공간 확보를 위해서 amount+1로 배열 사이즈를 측정
15+
Arrays.fill(dp, max); // 최소 개수를 구하는 것이기 때문에 max값으로 채웠다.
16+
dp[0] = 0; // 첫 요소만 max가 아닌 0으로 설정한다. ->
17+
// 그냥 0부터 amount까지 이중 for문 하는 것보다
18+
// j문에서 바깥 i의 코인값부터 인덱스로 시작하는 것이 같은 결과, 높은 성능.
19+
for (int coin : coins) {
20+
for (int j = coin; j <= amount; j++) {
21+
// dp[j - coin]: coin 동전을 하나 사용했을 때, 남은 금액 j - coin을 만드는 최소 동전 개수
22+
// 코인값을 인덱스로서 계산해야 한다는 것을 몰랐음 j-coin에서 한참을 헤맨....
23+
dp[j] = Math.min(dp[j], dp[j - coin] + 1);
1224
}
1325
}
14-
return dp[amount]>amount ? -1:dp[amount];
26+
return dp[amount] > amount ? -1 : dp[amount];
1527
}
1628
}

word-search/jinvicky.java

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,27 @@ class Solution {
22
public boolean exist(char[][] board, String word) {
33
int m = board.length;
44
int n = board[0].length;
5-
for(int i = 0; i < m; i++) {
6-
for(int j = 0; j < n; j++) {
7-
if(dfs(board, i, j, word, 0)) {
5+
for (int i = 0; i < m; i++) {
6+
for (int j = 0; j < n; j++) {
7+
if (dfs(board, i, j, word, 0)) {
88
return true;
99
}
1010
}
1111
}
1212
return false;
1313
}
1414

15-
boolean dfs(char[][] board,int i,int j,String word,int index){
16-
if(index == word.length()) return true;
17-
if(i<0 || j<0 || i>=board.length || j>=board[0].length) return false; // 범위를 벗어난 경우
18-
if(board[i][j] != word.charAt(index)) return false; // 일치 조건을 불만족하는 경우
15+
boolean dfs(char[][] board, int i, int j, String word, int index) {
16+
if (index == word.length()) return true;
17+
if (i < 0 || j < 0 || i >= board.length || j >= board[0].length) return false; // 범위를 벗어난 경우
18+
if (board[i][j] != word.charAt(index)) return false; // 일치 조건을 불만족하는 경우
1919

2020
char temp = board[i][j];
2121
board[i][j] = '#';
22-
boolean found = dfs(board, i+1, j, word, index+1)
23-
|| dfs(board, i-1, j, word, index+1)
24-
|| dfs(board, i, j+1, word, index+1)
25-
|| dfs(board, i, j-1, word, index+1);
22+
boolean found = dfs(board, i + 1, j, word, index + 1)
23+
|| dfs(board, i - 1, j, word, index + 1)
24+
|| dfs(board, i, j + 1, word, index + 1)
25+
|| dfs(board, i, j - 1, word, index + 1);
2626

2727
board[i][j] = temp;
2828
return found;
@@ -48,22 +48,44 @@ public boolean exist2(char[][] board, String word) {
4848
return false;
4949
}
5050

51+
// 백트래킹 인자 국룰 (인자로 받는다는 건 다음에 필요함 + 다음 재귀때 업데이트된 값이 필요해서)
52+
// 재귀여야 하기 때문에 2차원 input과 방향을 위한 i, j를 받도록 한다.
53+
// 매번 조건 일치를 확인하기 위한 target 값이 인자로 포함된다 (문제마다 다름)
54+
55+
// private boolean backtrack (원본 2차원 배열, 타겟, 2차원 방문 배열, i 방향 인덱스, j방향 인덱스, 조건부 target) {
56+
// break1. 조건을 만족하면 값을 반환
57+
// break2. i와 j의 범위가 0보다 작거나 원본 배열의 길이보다 크거나 같으면 탈락
58+
// break3. 방문배열[i][j]가 true거나 (이미 방문했음) 또는 문제의 만족 조건이 아닐 경우 탈락
59+
// 보통 break2, break3을 한번의 if문으로 작성하지만 난 그마저도 어려워서 한번 더 분리했다.
60+
//
61+
// action1. 방문배열[i][j] 를 true로 설정한다.
62+
// action2. i와 j를 위한 2차원 방향배열 템플릿을 선언한다.
63+
// action3. 방향은 무조건 동서남북 4방향 고정이다. 4만큼 반복되는 for문을 실행한다.
64+
// action3-1. dir[0], dir[1]을 i와 j에게 더해서 nextI, nextJ로 만들어 backtrack()에 전달한다. (이때 조건이 맞으면 return으로 break)
65+
// action4. return을 못한 경우 방문배열[i][j]를 false로 재설정한다.
66+
// action5. false 등을 리턴한다.
67+
// }
68+
69+
5170
private boolean backtrack(char[][] board, String word, boolean[][] visited, int i, int j, int index) {
5271
if (index == word.length()) {
5372
return true;
5473
}
5574

56-
// dfs를 풀 때는 배열 범위를 벗어나는 경우 break를 꼭 기억하기
57-
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || visited[i][j]
58-
|| board[i][j] != word.charAt(index)) {
75+
// dfs를 풀 때는 배열 범위를 벗어나는 경우는 모든 문제 공통이니 그냥 i,j기준으로 0와 length 생각하며 암기
76+
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) {
77+
return false;
78+
}
79+
80+
if (visited[i][j] || board[i][j] != word.charAt(index)) {
5981
return false;
6082
}
6183

6284
visited[i][j] = true;
6385

6486
// if문에서 작성하는 것이 눈에 안 익어서
6587
// direction 템플릿을 만들어서 for문으로 해결하는 암기법으로 변환
66-
int[][] directions = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; // 그냥 암기
88+
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; // 그냥 암기
6789

6890
for (int[] dir : directions) {
6991
// i가 y, j가 x인데 사실 1, -1, 0만 잘 설정하면 상관없음. 목적은 1, -1 1번씩 그리고 나머지는 0으로 채우는 것

0 commit comments

Comments
 (0)