From b7b5c205429aa4e6b79411a208c1d6924ade3fe5 Mon Sep 17 00:00:00 2001 From: Ryohei Sato <130881456+Satorien@users.noreply.github.com> Date: Thu, 14 Aug 2025 10:57:07 +0900 Subject: [PATCH] Create 153. Find Minimum in Rotated Sorted Array.md --- ...3. Find Minimum in Rotated Sorted Array.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Python3/153. Find Minimum in Rotated Sorted Array.md diff --git a/Python3/153. Find Minimum in Rotated Sorted Array.md b/Python3/153. Find Minimum in Rotated Sorted Array.md new file mode 100644 index 0000000..275fc4f --- /dev/null +++ b/Python3/153. Find Minimum in Rotated Sorted Array.md @@ -0,0 +1,78 @@ +## Step 1. Initial Solution + +- 二分探索的にやるにはどうすれば良いか + - どこかの基準と比較? + - 不等号の関係性でどこに最小値あるか分かる +- 最初の要素が最小値の場合は例外処理 + - もっといい方法があれば後で実装する + +```python +class Solution: + def findMin(self, nums: List[int]) -> int: + if nums[0] < nums[-1]: + return nums[0] + left = 0 + right = len(nums) - 1 + while left + 1 < right: + middle = (left + right) // 2 + if nums[left] < nums[middle]: + left = middle + else: + right = middle + return nums[right] + +``` + +### Complexity Analysis + +- 時間計算量:O(log n) +- 空間計算量:O(1) + +## Step 2. Alternatives + +- 最大値のところを踏み越えて最小値に乗ったら返すという方が自然かもしれない + - https://github.com/tokuhirat/LeetCode/pull/42/files#diff-88c7c13d92168adf69c9cdf4e197359b856835b1b48d08927346a143bf8f7a55R17 + - https://github.com/olsen-blue/Arai60/pull/42/files#diff-856251eccb601f9962fc7fdd308675f5690975413b45fe6be0950672570bc6caR44 +- これをもとになるべくシンプルに書く + - 場合分けすると確かにこれで十分 + +```python +class Solution: + def findMin(self, nums: List[int]) -> int: + left = 0 + right = len(nums) - 1 + while left < right: + middle = (left + right) // 2 + if nums[middle] < nums[right]: + right = middle + else: + left = middle + 1 + return nums[left] +``` + +- リスト内に重複がある場合はどうするか + - http://github.com/hroc135/leetcode/pull/40/files#diff-04f2110efff2f6666fa57b541ac1fa1b1de77a8edc09704f6266cc71cb7420c6R110 + - https://github.com/olsen-blue/Arai60/pull/42/files#diff-856251eccb601f9962fc7fdd308675f5690975413b45fe6be0950672570bc6caR82 + - 二分探索だと重複要素のどれに最初に当たるか分からない + - 基本は後ろ側を返すような処理になっている + - 見ている範囲(left, right, middle)で大小関係が分からない可能性がある + - 最初のif文でrightを更新すると戻れない + - 同じような形式で実装するのは難しそう + +## Step 3. Final Solution + +- シンプルな実装に落ち着いた + +```python +class Solution: + def findMin(self, nums: List[int]) -> int: + left = 0 + right = len(nums) - 1 + while left < right: + middle = (left + right) // 2 + if nums[middle] < nums[right]: + right = middle + else: + left = middle + 1 + return nums[left] +```