From 7248a385338ab5418a2c8a1bd82967cd51ee6baf Mon Sep 17 00:00:00 2001 From: kazukiii Date: Sat, 15 Jun 2024 23:00:02 -0700 Subject: [PATCH 1/2] =?UTF-8?q?step1,=20step2,=20step3=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arai60/two-sum/README.md | 36 ++++++++++++++++++++++++++++++++++++ arai60/two-sum/step1.py | 11 +++++++++++ arai60/two-sum/step2.py | 20 ++++++++++++++++++++ arai60/two-sum/step3.py | 11 +++++++++++ 4 files changed, 78 insertions(+) create mode 100644 arai60/two-sum/README.md create mode 100644 arai60/two-sum/step1.py create mode 100644 arai60/two-sum/step2.py create mode 100644 arai60/two-sum/step3.py diff --git a/arai60/two-sum/README.md b/arai60/two-sum/README.md new file mode 100644 index 0000000..7d885c2 --- /dev/null +++ b/arai60/two-sum/README.md @@ -0,0 +1,36 @@ +## 考察 +- 過去に何度も解いたことあり +- 方針は4つ思い浮かぶ + - 全探索 + - C(n, 2)パターンを全部調べる + - 今回はこの方針はスキップ + - time: O(n^2), space: O(1) + - ハッシュマップ + - 追加のメモリを使用する + - 足し算が可換(答えの順番が関係ない)ので1パスでOK + - 引き算とかだとおそらく1パスではできない + - time: O(n), space: O(n) + - ソートして二分探索 + - ソートしたら二分探索可能 + - time: O(n log n), space: O(1) + - ソートして2 pointers + - メモリO(1)の解法では、最速になると思う + - ソートがボトルネックになる + - time: O(n lon n), space: O(1) +- ハッシュマップを使った手法を選択 +- あとは実装 + +## Step1 +- ハッシュマップを使った方法を実装 +- time: O(n), space: O(n) + +## Step2 +- 2 pointersの手法でもやってみる +- ソートするとインデックスが変わるのでそこだけ注意した +- time: O(n log n), space: O(1) + +## Step3 +- ハッシュマップを使った方法で実装 +- 1回目: 1m02s +- 2回目: 55s +- 3回目: 47s diff --git a/arai60/two-sum/step1.py b/arai60/two-sum/step1.py new file mode 100644 index 0000000..ad15a37 --- /dev/null +++ b/arai60/two-sum/step1.py @@ -0,0 +1,11 @@ +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + n = len(nums) + num_to_index = {} + for i in range(n): + complement = target - nums[i] + if complement in num_to_index: + return [i, num_to_index[complement]] + num_to_index[nums[i]] = i + + raise Exception() diff --git a/arai60/two-sum/step2.py b/arai60/two-sum/step2.py new file mode 100644 index 0000000..4b63061 --- /dev/null +++ b/arai60/two-sum/step2.py @@ -0,0 +1,20 @@ +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + n = len(nums) + nums_with_index = [(nums[i], i) for i in range(n)] + nums_with_index.sort() + + left = 0 + right = n - 1 + while left < right: + num_left, index_left = nums_with_index[left] + num_right, index_right = nums_with_index[right] + sum_ = num_left + num_right + if sum_ == target: + return [index_left, index_right] + if sum_ < target: + left += 1 + else: + right -= 1 + + raise Exception() diff --git a/arai60/two-sum/step3.py b/arai60/two-sum/step3.py new file mode 100644 index 0000000..ad15a37 --- /dev/null +++ b/arai60/two-sum/step3.py @@ -0,0 +1,11 @@ +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + n = len(nums) + num_to_index = {} + for i in range(n): + complement = target - nums[i] + if complement in num_to_index: + return [i, num_to_index[complement]] + num_to_index[nums[i]] = i + + raise Exception() From 1867556859bd7d1ec8f2a0a57b20954a1bad37f6 Mon Sep 17 00:00:00 2001 From: kazukiii Date: Sun, 16 Jun 2024 16:22:27 -0700 Subject: [PATCH 2/2] =?UTF-8?q?step4=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arai60/two-sum/README.md | 13 +++++++++++-- arai60/two-sum/step4.py | 10 ++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 arai60/two-sum/step4.py diff --git a/arai60/two-sum/README.md b/arai60/two-sum/README.md index 7d885c2..7281ab1 100644 --- a/arai60/two-sum/README.md +++ b/arai60/two-sum/README.md @@ -12,11 +12,12 @@ - time: O(n), space: O(n) - ソートして二分探索 - ソートしたら二分探索可能 - - time: O(n log n), space: O(1) + - time: O(n log n), space: O(1) -> space: O(1)は勘違いだった。元のインデックスを保持する必要があるので、正しくはO(n) - ソートして2 pointers - メモリO(1)の解法では、最速になると思う - ソートがボトルネックになる - - time: O(n lon n), space: O(1) + - time: O(n lon n), space: O(1) -> space: O(1)は勘違いだった。元のインデックスを保持する必要があるので、正しくはO(n) + - ハッシュマップを使った手法を選択 - あとは実装 @@ -34,3 +35,11 @@ - 1回目: 1m02s - 2回目: 55s - 3回目: 47s + +## Step4 +- レビューを元に修正 +- 変数名を変更 + - complement -> complement_value +- Exceptionにメッセージを付与 + - 呼び出し元に対して親切に +- enumerateを使ってみた diff --git a/arai60/two-sum/step4.py b/arai60/two-sum/step4.py new file mode 100644 index 0000000..bd4e58d --- /dev/null +++ b/arai60/two-sum/step4.py @@ -0,0 +1,10 @@ +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + num_to_index = {} + for i, num in enumerate(nums): + complement_value = target - num + if complement_value in num_to_index: + return [i, num_to_index[complement_value]] + num_to_index[num] = i + + raise Exception('unreachable')