From f6394f256f682e286a837e6c5e06b86df6bb0c6d Mon Sep 17 00:00:00 2001 From: yamashita-ki Date: Thu, 18 Sep 2025 02:13:48 +0900 Subject: [PATCH 1/2] 739. Daily Temperatures --- 739. Daily Temperatures.md | 104 +++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 739. Daily Temperatures.md diff --git a/739. Daily Temperatures.md b/739. Daily Temperatures.md new file mode 100644 index 0000000..095df47 --- /dev/null +++ b/739. Daily Temperatures.md @@ -0,0 +1,104 @@ +## step1 とりあえず解く +- 計算量 + - 時間:O(N^2) + - 空間:O(N) +- 時間計算量をO(N)にする解決策を思いつけず、安直に全探索 + +```java +class Solution { + public int[] dailyTemperatures(int[] temperatures) { + int[] ans = new int[temperatures.length]; + for (int i = 0; i < temperatures.length - 1; i++) { + for (int j = i + 1; j < temperatures.length; j++) { + if (temperatures[i] < temperatures[j]) { + ans[i] = j - i; + break; + } + } + } + return ans; + } +} +``` + +## step2 他の人の回答を見て気になるところを修正 +- 計算量 + - 時間: O(N) + - 空間: O(N) +- 単調増加、単調減少するように要素が並べられたStackはMonotonic Stackというらしい +- for文の中にwhile文があるためぱっと見時間計算量がO(N^2)に見えたが、各要素一度しかpop, pushされないためO(N)になる +- 単にstackに積むだけではなく、stackに積む前に積むあたいがstackの一番上の値より大きいか確認する + - 大きければ、stackからpopする + - この一連の動作により単調減少のstackが作れる +- stackに積むのはindexだけでいいかなと思ったが、おそらくわかりやすさのために温度もセットで積んでいる + +```java +class Solution { + public int[] dailyTemperatures(int[] temperatures) { + ArrayDeque stack = new ArrayDeque<>(); + int[] ans = new int[temperatures.length]; + + for (int t = 0; t < temperatures.length; t++) { + int temperature = temperatures[t]; + while (!stack.isEmpty() && temperature > stack.peekLast()[0]) { + int[] pairs = stack.pollLast(); + ans[pairs[1]] = t - pairs[1]; + } + stack.add(new int[]{temperature, t}); + } + return ans; + } +} +``` + +- 計算量 + - 時間: O(N) + - 空間: O(N) +- 上記とは異なり右から(配列の後ろから)みていく方法 +- ただ配列を右から見ていくというのが直感的ではない、若干認知負荷が高く感じてしまった + +```java +class Solution { + public int[] dailyTemperatures(int[] temperatures) { + int length = temperatures.length; + Deque stack = new ArrayDeque<>(); + int[] result = new int[length]; + + for (int currentIndex = length - 1; currentIndex >= 0; currentIndex--) { + while (!stack.isEmpty() && temperatures[stack.peek()] <= temperatures[currentIndex]) { + stack.pop(); + } + + if (!stack.isEmpty()) { + result[currentIndex] = stack.peek() - currentIndex; + } + + stack.push(currentIndex); + } + + return result; + } +} +``` + +## step3 3回とく +- step2の配列の左から見ていく方法解いた + +```java +class Solution { + public int[] dailyTemperatures(int[] temperatures) { + int[] ans = new int[temperatures.length]; + Deque stack = new ArrayDeque<>(); + + for (int t = 0; t < temperatures.length; t++) { + int temperature = temperatures[t]; + while (!stack.isEmpty() && stack.peekLast()[1] < temperature) { + int[] pair = stack.pollLast(); + ans[pair[0]] = t - pair[0]; + } + stack.add(new int[]{t, temperature}); + } + return ans; + } +} +``` \ No newline at end of file From 567ec4d83edc857e06edee1bf08d1eb6df5cc816 Mon Sep 17 00:00:00 2001 From: yamashita-ki Date: Fri, 19 Sep 2025 03:02:12 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Step4=E3=81=A7Step1=E3=81=AB=E9=96=A2?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=81=84=E3=81=9F=E3=81=A0=E3=81=84=E3=81=9F?= =?UTF-8?q?=E6=8C=87=E6=91=98=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 739. Daily Temperatures.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/739. Daily Temperatures.md b/739. Daily Temperatures.md index 095df47..358ca49 100644 --- a/739. Daily Temperatures.md +++ b/739. Daily Temperatures.md @@ -101,4 +101,37 @@ class Solution { return ans; } } +``` + +## step4 いただいた指摘を元に書き直す +- step1で書いたコード関していただいた指摘: +>クラスやレコードクラスを作り、変数名やアクセサメソッド名で、どのような値が含まれているか、読み手にとって分かりやすくするとよいと思いました。 +>https://github.com/yamashita-ki/codingTest/pull/10#discussion_r2358390279 + +>t という変数名が何を表しているのわかりませんでした。短いスコープで、インデックスを表す 1 文字の変数には i がよく使われると思います。また、もう少しスコープが長くなる場合は、 i ですと何を表すか分かりにくくなると思います。その場合は、 day 等、中にどのような値が含まれているかが分かる英単語・英語句にするとよいと思います。 +>https://github.com/yamashita-ki/codingTest/pull/10#discussion_r2358402338 + +- いただいた指摘通り、Record型を新たに定義し、for文の中で使われる変数名を修正する + +```java +class Solution { + + private record DayTemperature(int day, int temperature) {} + + public int[] dailyTemperatures(int[] temperatures) { + Deque stack = new ArrayDeque<>(); + int[] ans = new int[temperatures.length]; + + for (int day = 0; day < temperatures.length; day++) { + int temperature = temperatures[day]; + while (!stack.isEmpty() && temperature > stack.peekLast().temperature()) { + DayTemperature previousDay = stack.pollLast(); + ans[previousDay.day()] = day - previousDay.day(); + } + stack.add(new DayTemperature(day, temperature)); + } + return ans; + } +} + ``` \ No newline at end of file