Skip to content

Commit 5c3a114

Browse files
committed
Add problem 'Longest Increasing Subsequence' and 'Best Time to Buy and Sell Stock II'
1 parent 38ce522 commit 5c3a114

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package io.github.juchanei.leetcodeJava;
2+
3+
import org.junit.jupiter.api.Nested;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.util.Arrays;
7+
8+
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
10+
// https://leetcode.com/problems/longest-increasing-subsequence/
11+
public class LongestIncreasingSubsequence {
12+
private int[] nums = null;
13+
private Memo memo = null;
14+
15+
public int lengthOfLIS(int[] nums) {
16+
this.nums = nums;
17+
this.memo = new Memo(nums.length + 1, nums.length + 1);
18+
19+
return recursion(null, 0);
20+
}
21+
22+
// NOTE: pivot 이 아직 선택되지 않은 경우 pivotIndex 를 null 로 한다.
23+
private int recursion(Integer pivotIndex, int index) {
24+
if (this.memo.contains(pivotIndex, index)) {
25+
return this.memo.get(pivotIndex, index);
26+
}
27+
28+
if (this.nums.length == index) return 0;
29+
30+
int result;
31+
if (pivotIndex == null || this.nums[pivotIndex] < this.nums[index]) {
32+
result = Math.max(
33+
recursion(index, index + 1) + 1,
34+
recursion(pivotIndex, index + 1)
35+
);
36+
} else {
37+
result = recursion(pivotIndex, index + 1);
38+
}
39+
40+
return this.memo.setAndGet(pivotIndex, index, result);
41+
}
42+
43+
static class Memo {
44+
private final int EMPTY = -1;
45+
private final int[][] memo;
46+
47+
Memo(int size1, int size2) {
48+
this.memo = new int[size1][size2];
49+
for (int[] l : this.memo) Arrays.fill(l, EMPTY);
50+
}
51+
52+
boolean contains(Integer i, int j) {
53+
if (i == null) return false;
54+
return this.memo[i][j] != EMPTY;
55+
}
56+
57+
int get(Integer i, int j) {
58+
return this.memo[i][j];
59+
}
60+
61+
int setAndGet(Integer i, int j, int value) {
62+
if (i == null) return value;
63+
return this.memo[i][j] = value;
64+
}
65+
}
66+
67+
@Nested
68+
class UnitTest {
69+
@Test
70+
public void example1() {
71+
// given
72+
int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};
73+
74+
// when
75+
int result = lengthOfLIS(nums);
76+
77+
// then
78+
assertEquals(4, result);
79+
}
80+
81+
@Test
82+
public void example2() {
83+
// given
84+
int[] nums = {0, 1, 0, 3, 2, 3};
85+
86+
// when
87+
int result = lengthOfLIS(nums);
88+
89+
// then
90+
assertEquals(4, result);
91+
}
92+
93+
@Test
94+
public void example3() {
95+
// given
96+
int[] nums = {7, 7, 7, 7, 7, 7, 7};
97+
98+
// when
99+
int result = lengthOfLIS(nums);
100+
101+
// then
102+
assertEquals(1, result);
103+
}
104+
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package io.github.juchanei.leetcodeKotlin
2+
3+
import org.assertj.core.api.BDDAssertions.then
4+
import org.junit.jupiter.api.Test
5+
import java.lang.Integer.max
6+
7+
// https://leetcode.com/explore/interview/card/top-interview-questions-easy/92/array/564/
8+
class BestTimeToBuyAndSellStockII {
9+
fun maxProfit(prices: IntArray): Int {
10+
val memo = mutableMapOf<Pair<Int, Int?>, Int>()
11+
12+
fun search(day: Int, buyPrice: Int? = null): Int {
13+
val cache = memo[day to buyPrice]
14+
if (cache != null) return cache
15+
16+
return when {
17+
// 기간이 끝났을 때 팔지 못한 주식이 있다면 손해로 책정한다
18+
prices.size == day -> {
19+
if (buyPrice == null) {
20+
0
21+
} else {
22+
-buyPrice
23+
}
24+
}
25+
// 가지고 있는 주식이 없는 경우 오늘 사거나 사지 않는다
26+
buyPrice == null -> {
27+
max(
28+
search(day + 1, prices[day]), // buy
29+
search(day + 1) // skip
30+
)
31+
}
32+
// 가지고 있는 주식의 가격이 오른 상태면 오늘 팔거나 팔지 않는다
33+
buyPrice < prices[day] -> {
34+
max(
35+
search(day + 1) + prices[day] - buyPrice, // sell
36+
search(day + 1, buyPrice), // skip
37+
)
38+
}
39+
// 가지고 있는 주식의 가격이 변동이 없거나 떨어져있으면
40+
// 오를때 까지 기다렸다가 팔거나 팔지 않는다
41+
else -> {
42+
val nextDay = (day + 1 until prices.size)
43+
.find { prices[day] < prices[it] }
44+
?: prices.size
45+
46+
max(
47+
search(nextDay) + prices[day] - buyPrice, // sell
48+
search(nextDay, buyPrice), // skip
49+
)
50+
}
51+
}.also {
52+
memo[day to buyPrice] = it
53+
}
54+
}
55+
56+
return search(0)
57+
}
58+
59+
@Test
60+
fun example1() {
61+
// given
62+
val prices = intArrayOf(7, 1, 5, 3, 6, 4)
63+
64+
// when
65+
val ret = maxProfit(prices)
66+
67+
// then
68+
then(ret).isEqualTo(7)
69+
}
70+
71+
@Test
72+
fun example2() {
73+
// given
74+
val prices = intArrayOf(1, 2, 3, 4, 5)
75+
76+
// when
77+
val ret = maxProfit(prices)
78+
79+
// then
80+
then(ret).isEqualTo(4)
81+
}
82+
83+
@Test
84+
fun example3() {
85+
// given
86+
val prices = intArrayOf(7, 6, 4, 3, 1)
87+
88+
// when
89+
val ret = maxProfit(prices)
90+
91+
// then
92+
then(ret).isEqualTo(0)
93+
}
94+
}

0 commit comments

Comments
 (0)