Skip to content

Commit e55891b

Browse files
author
weiy
committed
median of two sorted hard
1 parent 78a0944 commit e55891b

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

Diff for: Array/MedianOfTwoSorted.py

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
"""
2+
There are two sorted arrays nums1 and nums2 of size m and n respectively.
3+
4+
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
5+
6+
You may assume nums1 and nums2 cannot be both empty.
7+
8+
9+
10+
Example 1:
11+
12+
nums1 = [1, 3]
13+
nums2 = [2]
14+
15+
The median is 2.0
16+
Example 2:
17+
18+
nums1 = [1, 2]
19+
nums2 = [3, 4]
20+
21+
The median is (2 + 3)/2 = 2.5
22+
23+
求两个列表合并后的中位数。
24+
25+
时间复杂度要求O(log (m+n))
26+
27+
1. 直接sorted后取中位,时间复杂度为O((m+n)log(m+n))。
28+
2. 不用全部排序,本质上是一个求第k(s)小的数。 时间复杂度(O( (m+n)/2 ))还是没到要求的 O(log (m+n)),此版beat 43%~56%。
29+
# 打印真的是很慢,只打印一条很小的数据2.方法就会只能beat 7%..
30+
31+
3. 最后是 O(Log(m+n)) 的思路:
32+
求第k小的数的时候,有一种方法是每次去除 k // 2 个数,剩余 < 1个时就找到了最终要找的数。
33+
a = [1, 2, 4, 6]
34+
b = [3, 5, 7, 9]
35+
36+
此时的 k 为 8 // 2 = 4.
37+
k//2 = 2
38+
39+
则对比 a与b的第2个数也是下标为2-1哪个较小,较小的一组去除。然后循环即可。
40+
41+
因为是排过序的列表,不论哪一个列表中,去除 k//2 个数都不会去除目标。
42+
43+
因为只有k的一半,又是排过序的,假设a[k//2]<b[k//2]:
44+
1. 去除的值只有k的一半,
45+
2. 选择的是较小的那一组,那么组合起来:
46+
b[:k//2-1] + a[:k//2] + b[k//2-1]
47+
前两者无论如何都是比 b[k//2] 要小的,所以要么第k小的数是 b[k//2],要么不是,去除a[:k//2]一点问题都没有。
48+
49+
需要注意的问题:
50+
1. 若k//2大于某一个列表时,此时调整为所大于的列表的长度,不可能出现两个列表同时都小于的情况,
51+
除非写错了否则不可能 len(a)+len(b) // 4 > len(a)还 > len(b)
52+
a / 4 + b / 4 = a时 b / 4 = 3a / 4 -> b = 3a,3b/4 = 9a/4,所以 b/4 + a/4则不可能也大于b。
53+
2. 奇数在取k时向上取整。
54+
3. k//2向下取整。
55+
56+
这样每次去除的是k的一半,所以时间复杂度为O(log(k)) -> O(log((m+n)//2)) 符合要求。
57+
58+
beat 75%,前面的25%都是用的sorted,C扩展的sorted效率是最高的,也就是第一版,基本上是100%,但是这是作弊行为= =。
59+
60+
测试地址:
61+
https://leetcode.com/problems/median-of-two-sorted-arrays/description/
62+
63+
"""
64+
class Solution(object):
65+
66+
def findMedianSortedArrays(self, nums1, nums2):
67+
"""
68+
:type nums1: List[int]
69+
:type nums2: List[int]
70+
:rtype: float
71+
"""
72+
73+
length = len(nums1) + len(nums2)
74+
if length <= 2:
75+
return sum(nums1+nums2) / length
76+
raw_length = length
77+
78+
length = length // 2
79+
80+
if raw_length % 2 != 0:
81+
length += 1
82+
83+
while length > 1:
84+
85+
reduce_value = length // 2
86+
if nums1:
87+
if reduce_value > len(nums1):
88+
reduce_value = len(nums1)
89+
if nums2:
90+
if reduce_value > len(nums2):
91+
reduce_value = len(nums2)
92+
93+
nums1_k_value = nums1[reduce_value-1] if nums1 else float('inf')
94+
nums2_k_value = nums2[reduce_value-1] if nums2 else float('inf')
95+
96+
if nums1_k_value < nums2_k_value:
97+
nums1 = nums1[reduce_value:]
98+
else:
99+
nums2 = nums2[reduce_value:]
100+
101+
length -= reduce_value
102+
103+
104+
result = sorted(nums1[:2] + nums2[:2])
105+
if raw_length % 2 != 0:
106+
return result[0]
107+
108+
return sum(result[:2]) / 2
109+
110+
111+
# def findMedianSortedArrays(self, nums1, nums2):
112+
# """
113+
# :type nums1: List[int]
114+
# :type nums2: List[int]
115+
# :rtype: float
116+
# """
117+
118+
# length = len(nums1) + len(nums2)
119+
# if length <= 2:
120+
# return sum(nums1+nums2) / length
121+
# raw_length = length
122+
# length = length // 2
123+
# # Get kth minium number(s).
124+
# if raw_length % 2 == 0:
125+
# get = [length, length-1]
126+
# else:
127+
# get = [length]
128+
129+
# index_nums1 = 0
130+
# index_nums2 = 0
131+
# total_nums = 0
132+
# result = []
133+
134+
# while get:
135+
# if index_nums1 == len(nums1):
136+
# x = nums2[index_nums2]
137+
# index_nums2 += 1
138+
# elif index_nums2 == len(nums2):
139+
# x = nums1[index_nums1]
140+
# index_nums1 += 1
141+
# else:
142+
# if nums1[index_nums1] < nums2[index_nums2]:
143+
# x = nums1[index_nums1]
144+
# index_nums1 += 1
145+
# else:
146+
# x = nums2[index_nums2]
147+
# index_nums2 += 1
148+
149+
# if get[-1] == total_nums:
150+
# result.append(x)
151+
# get.pop()
152+
153+
# total_nums += 1
154+
155+
# return sum(result) / len(result)
156+
157+
# sorted.
158+
# def findMedianSortedArrays(self, nums1, nums2):
159+
# """
160+
# :type nums1: List[int]
161+
# :type nums2: List[int]
162+
# :rtype: float
163+
# """
164+
165+
# list3 = nums1 + nums2
166+
# list3.sort()
167+
168+
# return self.median(list3)
169+
170+
# def median(self, nums):
171+
172+
# length = len(nums)
173+
# if length % 2 == 0:
174+
# return (nums[(length // 2)-1] + nums[length // 2]) / 2
175+
176+
# return nums[length // 2]

0 commit comments

Comments
 (0)