From 3671ceb3ca8b83a0455b74ad3d7709b26ab8e03a Mon Sep 17 00:00:00 2001 From: shining-ai Date: Tue, 18 Jun 2024 15:50:09 +0000 Subject: [PATCH] =?UTF-8?q?=E3=80=90Grind75Hard=E3=80=9112=E5=95=8F?= =?UTF-8?q?=E7=9B=AE=204.=20Median=20of=20Two=20Sorted=20Arrays?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../4_Median of Two Sorted Arrays/level_1.py | 60 +++++++++++++++++++ .../4_Median of Two Sorted Arrays/level_2.py | 26 ++++++++ .../4_Median of Two Sorted Arrays/level_3.py | 24 ++++++++ 3 files changed, 110 insertions(+) create mode 100644 grind75_hard/4_Median of Two Sorted Arrays/level_1.py create mode 100644 grind75_hard/4_Median of Two Sorted Arrays/level_2.py create mode 100644 grind75_hard/4_Median of Two Sorted Arrays/level_3.py diff --git a/grind75_hard/4_Median of Two Sorted Arrays/level_1.py b/grind75_hard/4_Median of Two Sorted Arrays/level_1.py new file mode 100644 index 0000000..022d687 --- /dev/null +++ b/grind75_hard/4_Median of Two Sorted Arrays/level_1.py @@ -0,0 +1,60 @@ +# 2つのリストをマージしたものを作成していく(マージソートの要領) +# O(m + n) +class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + marged_list = [] + i = 0 + j = 0 + while i < len(nums1) and j < len(nums2): + if (len(nums1) + len(nums2)) // 2 < i + j: + break + if nums1[i] <= nums2[j]: + marged_list.append(nums1[i]) + i += 1 + else: + marged_list.append(nums2[j]) + j += 1 + else: + if len(nums1) <= i: + marged_list += nums2[j : (len(nums1) + len(nums2)) // 2 - i + 1] + else: + marged_list += nums1[i : (len(nums1) + len(nums2)) // 2 - j + 1] + + if (len(nums1) + len(nums2)) % 2 == 1: + return marged_list[-1] + else: + return (marged_list[-2] + marged_list[-1]) / 2 + + +# 2分探索 +# k番目に小さい要素を求める関数を作成 +# 小さい方からk-1個を削除すればk番目に小さいものは求められる。 +# nums1: [1, 4, 5, 7, 9] nums2: [2, 3, 6, 8] +# nums1[3]=5 > nums2[1]=3 なので、nums2[0], nums2[1]は中央値にならないから捨てる +# というように、小さい方からk-1個を削除していく +# O(log(min(m, n))) +class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + # k=0のとき最小値を返す + def get_kth_small(k, a_start, a_end, b_start, b_end): + if a_start >= a_end: + return nums2[k - a_start] + if b_start >= b_end: + return nums1[k - b_start] + a_middle = (a_start + a_end) // 2 + b_middle = (b_start + b_end) // 2 + if a_middle + b_middle < k: + if nums1[a_middle] < nums2[b_middle]: + return get_kth_small(k, a_middle + 1, a_end, b_start, b_end) + return get_kth_small(k, a_start, a_end, b_middle + 1, b_end) + if nums1[a_middle] < nums2[b_middle]: + return get_kth_small(k, a_start, a_end, b_start, b_middle) + return get_kth_small(k, a_start, a_middle, b_start, b_end) + + nums_length = len(nums1) + len(nums2) + if nums_length % 2 == 1: + return get_kth_small(nums_length // 2, 0, len(nums1), 0, len(nums2)) + return ( + get_kth_small(nums_length // 2 - 1, 0, len(nums1), 0, len(nums2)) + + get_kth_small(nums_length // 2, 0, len(nums1), 0, len(nums2)) + ) / 2 diff --git a/grind75_hard/4_Median of Two Sorted Arrays/level_2.py b/grind75_hard/4_Median of Two Sorted Arrays/level_2.py new file mode 100644 index 0000000..04cb053 --- /dev/null +++ b/grind75_hard/4_Median of Two Sorted Arrays/level_2.py @@ -0,0 +1,26 @@ +# 2分探索 +# インデックスではなく、配列を渡すように修正 +class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + def get_kth_small(k, nums1, nums2): + if not nums1: + return nums2[k] + if not nums2: + return nums1[k] + middle_1 = len(nums1) // 2 + middle_2 = len(nums2) // 2 + if middle_1 + middle_2 < k: + if nums1[middle_1] < nums2[middle_2]: + return get_kth_small(k - middle_1 - 1, nums1[middle_1 + 1 :], nums2) + return get_kth_small(k - middle_2 - 1, nums1, nums2[middle_2 + 1 :]) + if nums1[middle_1] < nums2[middle_2]: + return get_kth_small(k, nums1, nums2[:middle_2]) + return get_kth_small(k, nums1[:middle_1], nums2) + + nums_length = len(nums1) + len(nums2) + if nums_length % 2 == 1: + return get_kth_small(nums_length // 2, nums1, nums2) + return ( + get_kth_small(nums_length // 2 - 1, nums1, nums2) + + get_kth_small(nums_length // 2, nums1, nums2) + ) / 2 diff --git a/grind75_hard/4_Median of Two Sorted Arrays/level_3.py b/grind75_hard/4_Median of Two Sorted Arrays/level_3.py new file mode 100644 index 0000000..dab220f --- /dev/null +++ b/grind75_hard/4_Median of Two Sorted Arrays/level_3.py @@ -0,0 +1,24 @@ +class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + def get_kth_small(k, nums1, nums2): + if not nums1: + return nums2[k] + if not nums2: + return nums1[k] + middle_1 = len(nums1) // 2 + middle_2 = len(nums2) // 2 + if middle_1 + middle_2 < k: + if nums1[middle_1] < nums2[middle_2]: + return get_kth_small(k - middle_1 - 1, nums1[middle_1 + 1 :], nums2) + return get_kth_small(k - middle_2 - 1, nums1, nums2[middle_2 + 1 :]) + if nums1[middle_1] < nums2[middle_2]: + return get_kth_small(k, nums1, nums2[:middle_2]) + return get_kth_small(k, nums1[:middle_1], nums2) + + nums_length = len(nums1) + len(nums2) + if nums_length % 2 == 1: + return get_kth_small(nums_length // 2, nums1, nums2) + return ( + get_kth_small(nums_length // 2 - 1, nums1, nums2) + + get_kth_small(nums_length // 2, nums1, nums2) + ) / 2