From ad1aa0cc70faf7de2fcfa268d15ba3f260f4c762 Mon Sep 17 00:00:00 2001 From: busker <165013324+hiroki-horiguchi-dev@users.noreply.github.com> Date: Sat, 21 Mar 2026 15:18:13 +0900 Subject: [PATCH 1/2] Create 373.md --- heap-priorityQueue/373.md | 143 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 heap-priorityQueue/373.md diff --git a/heap-priorityQueue/373.md b/heap-priorityQueue/373.md new file mode 100644 index 0000000..a1e106d --- /dev/null +++ b/heap-priorityQueue/373.md @@ -0,0 +1,143 @@ +# 1st +- 問題: [373. Find K Pairs with Smallest Sums](https://leetcode.com/problems/find-k-pairs-with-smallest-sums/description/) +- コメント集: []() +- 条件 + - `1 <= nums1.length, nums2.length <= 10^5` + - `-10^9 <= nums1[i], nums2[i] <= 10^9` + - `nums1 and nums2 both are sorted in non-decreasing order.` + - `1 <= k <= 10^4` + - `k <= nums1.length * nums2.length` + +- 方針 + - 二重ループを回し切ったら`10^10`で時間的に間に合わない + - 問題文に `nums1 and nums2 sorted in non-decreasing-order` と、太字で書いてあるのでこれを有効に使えば良さそう + - どちらかの配列を固定して、走査していく方針となるはず + +## 1st +- 30分 +- nums1, nums2 の配列サイズ以上の k が与えられた時を0から考えつくのは初見は難しい気がする、これは答えみないとわからんよ。。 +- 勘違いして解いてしまったけど備忘録として残しておく +```java +class Solution { + public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { + List> result = new ArrayList<>(); + PriorityQueue smallest = new PriorityQueue<>((a,b) -> a[0] - b[0]); + int counter = 0; + + for (int num1 : nums1) { + if (counter == k) { + break; + } + for (int num2 : nums2) { + smallest.add(new int[]{num1 + num2, num1, num2}); + } + int[] temp = smallest.poll(); + List pair = new ArrayList<>(); + pair.add(temp[1]); + pair.add(temp[2]); + result.add(pair); + counter++; + } + + return result; + } +} +``` + +- 答えを見た +```java +class Solution { + public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { + List> result = new ArrayList<>(); + + PriorityQueue smallestQueue = new PriorityQueue<>((a, b) -> a[0] - b[0]); + + for (int i = 0; i < nums1.length; i++) { + smallestQueue.add(new int[]{nums1[i] + nums2[0], i, 0}); + } + + while (result.size() < k && !smallestQueue.isEmpty()) { + int[] smallest = smallestQueue.poll(); + int i = smallest[1]; + int j = smallest[2]; + + List pair = new ArrayList<>(); + pair.add(nums1[i]); + pair.add(nums2[j]); + result.add(pair); + + // ここが肝. i = 0, j = 0 が1周目のループで確定していて、i = 1 ~ i.length, j = 0 しか smallestQueue には入っていない + // 次の最小値のペアとして考えられるのは i = 0, j = 1 なので、これを smallestQueue 保存する + // 2周目以降がちょっと追いづらくて、poll() された要素の i, j + 1 を次の候補とするので、書き出したケースによっては意味不明な当たり方をしているように見えてしまい、最初の理解でつまづきがち + if (j + 1 < nums2.length) { + smallestQueue.add(new int[]{nums1[i] + nums2[j + 1], i, j + 1}); + } + } + return result; + } +} +``` + +## 2nd +- 読みやすく整形 +```java +class Solution { + public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { + List> result = new ArrayList<>(); + PriorityQueue indexPairQueue = new PriorityQueue<>((a, b) -> a[0] - b[0]); + + for (int i = 0; i < nums1.length; i++) { + indexPairQueue.add(new int[]{nums1[i] + nums2[0], i, 0}); + } + + while (result.size() < k && !indexPairQueue.isEmpty()) { + int[] sumAndIndices = indexPairQueue.poll(); + int i = sumAndIndices[1]; + int j = sumAndIndices[2]; + + List pair = new ArrayList<>(); + pair.add(nums1[i]); + pair.add(nums2[j]); + result.add(pair); + + if (j + 1 < nums2.length) { + indexPairQueue.add(new int[]{nums1[i] + nums2[j + 1], i, j + 1}); + } + } + + return result; + } +} +``` + +## 3rd +- 3回書き直し済 +```java +class Solution { + public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { + List> result = new ArrayList<>(); + PriorityQueue indexPairQueue = new PriorityQueue<>((a, b) -> a[0] - b[0]); + + for (int i = 0; i < nums1.length; i++) { + indexPairQueue.add(new int[]{nums1[i] + nums2[0], i, 0}); + } + + while (result.size() < k && !indexPairQueue.isEmpty()) { + int[] sumAndIndices = indexPairQueue.poll(); + int i = sumAndIndices[1]; + int j = sumAndIndices[2]; + + List pair = new ArrayList<>(); + pair.add(nums1[i]); + pair.add(nums2[j]); + result.add(pair); + + if (j + 1 < nums2.length) { + indexPairQueue.add(new int[]{nums1[i] + nums2[j + 1], i, j + 1}); + } + } + + return result; + } +} +``` \ No newline at end of file From f9d7dd5941e221e4a0a859550f2d7638fe98c9dd Mon Sep 17 00:00:00 2001 From: busker <165013324+hiroki-horiguchi-dev@users.noreply.github.com> Date: Sat, 21 Mar 2026 17:59:43 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E9=9B=86=E3=82=92=E8=AA=AD=E3=82=93=E3=81=A7=E9=87=8D=E8=A6=81?= =?UTF-8?q?=E3=81=A8=E6=84=9F=E3=81=98=E3=81=9F=E7=AE=87=E6=89=80=E3=82=92?= =?UTF-8?q?=E5=8F=96=E3=82=8A=E3=81=93=E3=82=93=E3=81=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- heap-priorityQueue/373.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/heap-priorityQueue/373.md b/heap-priorityQueue/373.md index a1e106d..592c6c8 100644 --- a/heap-priorityQueue/373.md +++ b/heap-priorityQueue/373.md @@ -1,6 +1,12 @@ # 1st - 問題: [373. Find K Pairs with Smallest Sums](https://leetcode.com/problems/find-k-pairs-with-smallest-sums/description/) -- コメント集: []() +- コメント集: [373. Find K Pairs with Smallest Sums](https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/mobilebasic#h.527w0lse8gbd) + - 気になったコメント + - [コメント1](https://discord.com/channels/1084280443945353267/1201211204547383386/1206515949579145216) + - 問題設定では必ずkはある想定なんでしたっけ? --> なるほどなと思う、k, num1,num2 がそれぞれ条件を満たしていないときに IllegalArgumentException を投げるように変更 + - [コメント2](https://discord.com/channels/1084280443945353267/1231966485610758196/1268091954537959437) + - なるほど、、そういう[方針](https://github.com/TORUS0818/leetcode/pull/12/changes)で皆さんといているんですね + - 最初に全然思いつかなかったです - 条件 - `1 <= nums1.length, nums2.length <= 10^5` - `-10^9 <= nums1[i], nums2[i] <= 10^9` @@ -45,6 +51,8 @@ class Solution { ``` - 答えを見た +- 時間計算量: nums1.length = n とすると、`O((n + k) log n)` +- 空間計算量: nums1.length = n とすると、`O(n + k)` ```java class Solution { public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { @@ -83,6 +91,12 @@ class Solution { ```java class Solution { public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { + if (k <= 0) { + throw new IllegalArgumentException("kには自然数を指定してください"); + } + if (nums1.length == 0 || nums2.length == 0) { + throw new IllegalArgumentException("サイズ1以上の配列を渡してください"); + } List> result = new ArrayList<>(); PriorityQueue indexPairQueue = new PriorityQueue<>((a, b) -> a[0] - b[0]); @@ -115,6 +129,12 @@ class Solution { ```java class Solution { public List> kSmallestPairs(int[] nums1, int[] nums2, int k) { + if (k <= 0) { + throw new IllegalArgumentException("kには自然数を指定してください"); + } + if (nums1.length == 0 || nums2.length == 0) { + throw new IllegalArgumentException("サイズ1以上の配列を渡してください"); + } List> result = new ArrayList<>(); PriorityQueue indexPairQueue = new PriorityQueue<>((a, b) -> a[0] - b[0]); @@ -140,4 +160,5 @@ class Solution { return result; } } +``` ``` \ No newline at end of file