From 777b037ee5cde4f29c00258655bdf9aa3636f18a Mon Sep 17 00:00:00 2001 From: Ryo Oshima Date: Tue, 10 Jun 2025 18:12:18 +0900 Subject: [PATCH 1/2] 121. Best Time to Buy and Sell Stock --- .../solution1_1.java | 33 ++++++++++++++ .../solution1_2.java | 35 +++++++++++++++ .../solution2_1.java | 43 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 121. Best Time to Buy and Sell Stock/solution1_1.java create mode 100644 121. Best Time to Buy and Sell Stock/solution1_2.java create mode 100644 121. Best Time to Buy and Sell Stock/solution2_1.java diff --git a/121. Best Time to Buy and Sell Stock/solution1_1.java b/121. Best Time to Buy and Sell Stock/solution1_1.java new file mode 100644 index 0000000..831cf14 --- /dev/null +++ b/121. Best Time to Buy and Sell Stock/solution1_1.java @@ -0,0 +1,33 @@ +/* + * ・概要 + * 自力解法 + * 解法は全探索、DPすぐに思い浮かんだ。5分ほどでAC + * DP解法としては、あるindexの要素に着目したとき、利益はそれまでの最低の価格で買った時との差分であるので、最低値のみを保持して毎回現在との差分を取れば良い。 + * これは1回の配列走査でおわるのでO(n)となり、変数だけもっておけばいいので空間もO(1) + * + * ・計算量 + * O(n):nは配列の要素数 + * O(1) + * + * ・その他 + * せっかくなのであとで、全探索versionもかく。 + * ループは0でなく1からで良さそう。 + */ + +public class solution1_1 { + public int maxProfit(int[] prices) { + if (prices.length == 0 || prices.length == 1) { + return 0; + } + int maxProfit = 0; + int minPriceBefore = prices[0]; + for (int i = 0; i < prices.length; i++) { + int currentMaxProfit = Math.max(0, prices[i] - minPriceBefore); + maxProfit = Math.max(maxProfit, currentMaxProfit); + if (prices[i] < minPriceBefore) { + minPriceBefore = prices[i]; + } + } + return maxProfit; + } +} diff --git a/121. Best Time to Buy and Sell Stock/solution1_2.java b/121. Best Time to Buy and Sell Stock/solution1_2.java new file mode 100644 index 0000000..e1ffdb8 --- /dev/null +++ b/121. Best Time to Buy and Sell Stock/solution1_2.java @@ -0,0 +1,35 @@ +/* + * ・概要 + * 自力解法 + * 全探索バージョン、二重ループ + * DP解法としては、あるindexの要素に着目したとき、利益はそれまでの最低の価格で買った時との差分であるので、最低値のみを保持して毎回現在との差分を取れば良い。 + * これは1回の配列走査でおわるのでO(n)となり、変数だけもっておけばいいので空間もO(1) + * + * ・計算量 + * O(n^2):今回は最大でn=10^5となるので、最大10Gかかる。Macだとクロック数が数GHzなので、単純計算でも3sくらいはかかる。 + * Javaのオーバーヘッドを加味して、だいたい3倍くらいかかる(10sくらい)という予想 + * 以前共有いただいたJavaとかのベンチマーク + * https://benchmarksgame-team.pages.debian.net/benchmarksgame/box-plot-summary-charts.html + * https://github.com/niklas-heer/speed-comparison + * + * O(1) + * + * ・その他 + * せっかくなのであとで、全探索versionもかく。 + * ループは0でなく1からで良さそう。 + */ + +public class solution1_2 { + public int maxProfit(int[] prices) { + if (prices.length == 0 || prices.length == 1) { + return 0; + } + int maxProfit = 0; + for (int i = 0; i < prices.length; i++) { + for (int j = 0; j < i; j++) { + maxProfit = Math.max(maxProfit, prices[i] - prices[j]); + } + } + return maxProfit; + } +} diff --git a/121. Best Time to Buy and Sell Stock/solution2_1.java b/121. Best Time to Buy and Sell Stock/solution2_1.java new file mode 100644 index 0000000..18ef466 --- /dev/null +++ b/121. Best Time to Buy and Sell Stock/solution2_1.java @@ -0,0 +1,43 @@ +/* +* https://github.com/irohafternoon/LeetCode/pull/40/files +* たしかにif文で分岐させると意味合い的にもわけられていいかも +* +* https://github.com/huyfififi/coding-challenges/pull/4/files +* たしかに後ろからみていくのも悪くない。直感的なのは左からみていくだが、(未来 - 過去)という構図がわかりやすいなと思った。 +* +* https://github.com/seal-azarashi/leetcode/pull/35/files +* 大体同じ +* +* +* 以下では後ろからみていく実装を行う。 +* +* ・計算量 +* time: O(n), space: O(1) + +* ・その他 +* maxPriceInFutureはやりすぎかも、maxPriceだけでも十分伝わりそう +* +* https://github.com/colorbox/leetcode/pull/6/files +* https://github.com/goto-untrapped/Arai60/pull/58/files#r1782742318 +* 関数型的考え、scanlを調べたところ、累積結果をすべて返す関数らしく、scanl (+) 0 [1, 2, 3, 4] -- => [0, 1, 3, 6, 10], この例だと累積和だ +* ということで最小値と最大値を累積していき、最後にその結果の配列を元にprofitをみていくことだと解釈した。 + +*/ + +public class solution2_1 { + public int maxProfit(int[] prices) { + if (prices.length == 0 || prices.length == 1) { + return 0; + } + int maxProfit = 0; + int maxPriceInFuture = prices[prices.length - 1]; + for (int i = prices.length - 2; i >= 0; i--) { + if (maxPriceInFuture < prices[i]) { + maxPriceInFuture = prices[i]; + continue; + } + maxProfit = Math.max(maxProfit, maxPriceInFuture - prices[i]); + } + return maxProfit; + } +} From 701bfa5e6da1e779e01931b3dd8486093daffadf Mon Sep 17 00:00:00 2001 From: Ryo Oshima Date: Tue, 10 Jun 2025 18:13:43 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 121. Best Time to Buy and Sell Stock/solution1_2.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/121. Best Time to Buy and Sell Stock/solution1_2.java b/121. Best Time to Buy and Sell Stock/solution1_2.java index e1ffdb8..880c251 100644 --- a/121. Best Time to Buy and Sell Stock/solution1_2.java +++ b/121. Best Time to Buy and Sell Stock/solution1_2.java @@ -12,11 +12,7 @@ * https://benchmarksgame-team.pages.debian.net/benchmarksgame/box-plot-summary-charts.html * https://github.com/niklas-heer/speed-comparison * - * O(1) * - * ・その他 - * せっかくなのであとで、全探索versionもかく。 - * ループは0でなく1からで良さそう。 */ public class solution1_2 {