From 679f4029482062ede9217f77157bdd79cc8599ba Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Sat, 27 Apr 2024 02:28:02 +0900 Subject: [PATCH 1/3] phase1 --- .../search_in_rotated_sorted_array/phase1.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 arai60/search_in_rotated_sorted_array/phase1.py diff --git a/arai60/search_in_rotated_sorted_array/phase1.py b/arai60/search_in_rotated_sorted_array/phase1.py new file mode 100644 index 0000000..de4b41c --- /dev/null +++ b/arai60/search_in_rotated_sorted_array/phase1.py @@ -0,0 +1,36 @@ +# 最小値のindexを見つけてそこで左右に分割して考えると分割したところは増加列になっていることを利用する +class Solution: + def search(self, nums: List[int], target: int) -> int: + def _find_minimum_index(): + # 最小値の数がどこにあるかをO(logN)で見つける + left = 0 + right = len(nums) - 1 + while left != right: + mid = (left + right) // 2 + if nums[mid] < nums[right]: + right = mid + else: + left = mid + 1 + return right + + min_index = _find_minimum_index() + if nums[min_index] <= target <= nums[-1]: + left = min_index + right = len(nums) - 1 + else: + left = 0 + right = min_index - 1 + + # targetを探す + while left < right: + mid = (left + right) // 2 + if nums[mid] == target: + return mid + elif nums[mid] < target: + left = mid + 1 + elif nums[mid] > target: + right = mid - 1 + + if nums[right] == target: + return right + return -1 \ No newline at end of file From ec2d0d0c3642f00397204f1bee9096c7e3d28816 Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Sat, 27 Apr 2024 02:28:10 +0900 Subject: [PATCH 2/3] phase2 --- .../search_in_rotated_sorted_array/phase2.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 arai60/search_in_rotated_sorted_array/phase2.py diff --git a/arai60/search_in_rotated_sorted_array/phase2.py b/arai60/search_in_rotated_sorted_array/phase2.py new file mode 100644 index 0000000..3121f5c --- /dev/null +++ b/arai60/search_in_rotated_sorted_array/phase2.py @@ -0,0 +1,46 @@ +""" +Reference +shining-aiさん: https://github.com/shining-ai/leetcode/pull/43/files +bisectの引数で探索範囲を絞れることを知る。ただ, この場合rightの調整にphase1で作ったものよりも一工夫必要で, numsのとりうるindexより+1しないとダメだった +ちょっと調べてみたところhttps://docs.python.org/ja/3.6/library/bisect.html +このようにbisectの引数が[lo:hi]となるスライスの中を探しているからだった。 + +hayashi-ayさん: https://github.com/hayashi-ay/leetcode/pull/49/files +考察の +nums[i]とnums[-1]を比較してnums[i]の方が大きい場合は左側は昇順に並んでいる。それ以外の場合は右側が昇順に並んでいる。 +targetが昇順に並んでいる側の範囲にあればそちらを見に行く。そうでなければ反対側を見に行く。 +を利用して, 1回のbinary searchでindexを見つけることができていた。認知負荷的には重い気がしたけど, 効率を求めると良い場合があるのかもしれない。 +leetcode上での計測結果は誤差の範囲だった。 + +""" +import bisect + +# 最小値のindexを見つけてそこで左右に分割して考えると分割したところは増加列になっていることを利用する +class Solution: + def search(self, nums: List[int], target: int) -> int: + def _find_minimum_index(): + # 最小値の数がどこにあるかをO(logN)で見つける + left = 0 + right = len(nums) - 1 + while left != right: + mid = (left + right) // 2 + if nums[mid] < nums[right]: + right = mid + else: + left = mid + 1 + return right + + min_index = _find_minimum_index() + if nums[min_index] <= target <= nums[-1]: + left = min_index + right = len(nums) + else: + left = 0 + right = min_index + + # targetを探す + target_index = bisect.bisect_left(nums, target, left, right) + + if nums[target_index] == target: + return target_index + return -1 \ No newline at end of file From 39ebf2dd914707cc7b419b68e6ed701878cd8297 Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Sat, 27 Apr 2024 02:28:20 +0900 Subject: [PATCH 3/3] phase3 --- .../search_in_rotated_sorted_array/phase3.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 arai60/search_in_rotated_sorted_array/phase3.py diff --git a/arai60/search_in_rotated_sorted_array/phase3.py b/arai60/search_in_rotated_sorted_array/phase3.py new file mode 100644 index 0000000..068f082 --- /dev/null +++ b/arai60/search_in_rotated_sorted_array/phase3.py @@ -0,0 +1,28 @@ +import bisect + +class Solution: + def search(self, nums: List[int], target: int) -> int: + def _find_minimum_index(): + # 二分探索でnumsの最小値のindexを見つける + left = 0 + right = len(nums) - 1 + while left != right: + mid = (left + right) // 2 + if nums[mid] < nums[right]: + right = mid + else: + left = mid + 1 + return right + + min_index = _find_minimum_index() + if nums[min_index] <= target <= nums[-1]: + left = min_index + right = len(nums) + else: + left = 0 + right = min_index + + target_index = bisect.bisect_left(nums, target, left, right) + if nums[target_index] == target: + return target_index + return -1 \ No newline at end of file