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