diff --git a/153_find_minimum_in_rotated_sorted_array_medium/README.md b/153_find_minimum_in_rotated_sorted_array_medium/README.md new file mode 100644 index 0000000..69fca9c --- /dev/null +++ b/153_find_minimum_in_rotated_sorted_array_medium/README.md @@ -0,0 +1,30 @@ +# 問題へのリンク +[Find Minimum in Rotated Sorted Array - LeetCode](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/) + +# 言語 +Python + +# 問題の概要 +回転された昇順ソート配列から最小値を見つける。配列の回転とは、要素を一つずつ右にずらす操作を指す。例えば、`[3, 4, 5, 1, 2]`は`[1, 2, 3, 4, 5]`を回転させた結果である。 +本問では時間計算量が`O(log(n))`であることが求められる。 + +# 自分の解法 +二分探索を用いて、回転された配列の最小値を見つける。配列の中央の要素と端の要素を比較し、どちら側に最小値が存在するかを判断する。 +元の配列を`a0 a0 nums[right]`が成り立つように、`left`と`right`の更新を行う。 + +- 時間計算量:`O(log(n))` +- 空間計算量:`O(1)` + +## step2 +- `L`, `R`をそれぞれ`left`, `right`に置き換える。 + - 大文字はPEP8に反する。大文字は定数に使うべき。 + - 1文字の変数名はPEP8に反する + - `L`, `R`が市民権を得ているのはatcoderだけ + + +# 次に解く問題の予告 +- [Evaluate Division - LeetCode](https://leetcode.com/problems/evaluate-division/description/) +- [Subsets - LeetCode](https://leetcode.com/problems/subsets/) diff --git a/153_find_minimum_in_rotated_sorted_array_medium/meguru.py b/153_find_minimum_in_rotated_sorted_array_medium/meguru.py new file mode 100644 index 0000000..ef48608 --- /dev/null +++ b/153_find_minimum_in_rotated_sorted_array_medium/meguru.py @@ -0,0 +1,27 @@ +# +# @lc app=leetcode id=153 lang=python3 +# +# [153] Find Minimum in Rotated Sorted Array +# + +# @lc code=start +class Solution: + def findMin(self, nums: list[int]) -> int: + def is_index_value_leq_to_last(index: int) -> bool: + if index < 0 or len(nums) <= index: + return False + return nums[-1] >= nums[index] + + left = -1 + right = len(nums) - 1 + while (right - left) > 1: + mid = (right + left) // 2 + if is_index_value_leq_to_last(mid): + right = mid + else: + left = mid + + return nums[right] + + +# @lc code=end diff --git a/153_find_minimum_in_rotated_sorted_array_medium/step1.py b/153_find_minimum_in_rotated_sorted_array_medium/step1.py new file mode 100644 index 0000000..9545da2 --- /dev/null +++ b/153_find_minimum_in_rotated_sorted_array_medium/step1.py @@ -0,0 +1,35 @@ +# +# @lc app=leetcode id=153 lang=python3 +# +# [153] Find Minimum in Rotated Sorted Array +# + + +# @lc code=start +class Solution: + def findMin(self, nums: list[int]) -> int: + if not nums: + raise ValueError("nums must have at least one element.") + elif len(nums) <= 2: + return min(nums) + + L = 0 + R = len(nums) - 1 + # no rotation + if nums[L] <= nums[R]: + return nums[L] + + # nums[R] < nums[L] always holds + while (R - L) > 1: + mid = (R + L) // 2 + if nums[mid] < nums[R]: + R = mid + # nums[L] < nums[mid]: + else: + L = mid + + # R-L = 1, nums[L]: largest, and nums[R]: smallest + return nums[R] + + +# @lc code=end diff --git a/153_find_minimum_in_rotated_sorted_array_medium/step2.py b/153_find_minimum_in_rotated_sorted_array_medium/step2.py new file mode 100644 index 0000000..37c66d3 --- /dev/null +++ b/153_find_minimum_in_rotated_sorted_array_medium/step2.py @@ -0,0 +1,35 @@ +# +# @lc app=leetcode id=153 lang=python3 +# +# [153] Find Minimum in Rotated Sorted Array +# + + +# @lc code=start +class Solution: + def findMin(self, nums: list[int]) -> int: + if not nums: + raise ValueError("nums must have at least one element.") + elif len(nums) <= 2: + return min(nums) + + left = 0 + right = len(nums) - 1 + # Array is not rotated (Already sorted in ascending order) + if nums[left] <= nums[right]: + return nums[left] + + # nums[right] < nums[left] always holds during binary search + while (right - left) > 1: + mid = left + (right - left) // 2 + if nums[mid] <= nums[right]: + right = mid + # nums[left] <= nums[mid] + else: + left = mid + + # nums[left]: largest, and nums[right]: smallest + return nums[right] + + +# @lc code=end diff --git a/153_find_minimum_in_rotated_sorted_array_medium/step3.py b/153_find_minimum_in_rotated_sorted_array_medium/step3.py new file mode 100644 index 0000000..fb0df8b --- /dev/null +++ b/153_find_minimum_in_rotated_sorted_array_medium/step3.py @@ -0,0 +1,29 @@ +# +# @lc app=leetcode id=153 lang=python3 +# +# [153] Find Minimum in Rotated Sorted Array +# + + +# @lc code=start +class Solution: + def findMin(self, nums: list[int]) -> int: + left = 0 + right = len(nums) - 1 + # case 1. already sorted + if nums[left] <= nums[right]: + return nums[left] + + # case 2. rotated + # find min using binary search. nums[left] > nums[right] always holds + while right - left > 1: + mid = left + (right - left) // 2 + if nums[left] < nums[mid]: + left = mid + else: + right = mid + + return nums[right] + + +# @lc code=end