浅沫记忆 发表于 2021-12-12 20:17:59

#yyds干货盘点#两个排序数组的中位数,“最”有技术含量的解法

这是我参与11月更文挑战的第10天。
一、写在前面
LeetCode 第一题两数之和传输门:听说你还在写双层for循环解两数之和?
今天给大家分享的是LeetCode 数组与字符串 第二题:两个排序数组的中位数,为面试而生,期待你的加入。
二、今日题目
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。
请找出这两个有序数组的中位数。 要求算法的时间复杂度为 O(log (m+n))。
你可以假设 nums1 和 nums2 不同时为空。
示例:
# 示例1
nums1 =
nums2 =

中位数是 2.0

# 示例2
nums1 =
nums2 =

中位数是 (2 + 3)/2 = 2.5三、 分析
这个题目好像比第一个题目还要更简单一些,唯一一点可能让大家犯迷糊的地方就是要求时间复杂度为O(log (m+n)),什么是时间复杂度呢?
算法的时间复杂度是一个函数,它定性描述了该算法的运行时间,一般用O表示,一般我们根据一段代码里,代码重复执行的次数来定义时间复杂度,如果是一个常数n,我们就说算法时间复杂度为O(1),类似的还有O(x),O(x^2),O(logx)...
四、解题

[*]方法一:
这是我见这个题目第一眼就想到的方法,分三步:<br>
1.两个数组拼接,排序<br>
2.测拼接后数组长度,判断奇偶<br>
3.测出中位数下标,求出中位数class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
    """
    :type nums1: List
    :type nums2: List
    :rtype: float
    """
    # 拼接数组
    nums = nums1+nums2
    # 排序
    nums.sort()
    # 测长度
    l = len(nums)
    # 判断奇偶求中位数下标
    if l%2 == 0 :
      index =
    else:
      index =
    # 求中位数
    median_num = (nums]+nums])/2.0
    return median_num
nums1 =
nums2 =
s0 = Solution()
median_num = s0.findMedianSortedArrays(nums1,nums2)
print(median_num)
简化该思想:pythonclass Solution:
def findMedianSortedArrays(self, nums1, nums2):

      """
      :type nums1: List
      :type nums2: List
      :rtype: float
      """
      t = nums1+nums2 # 两个拼接
      t.sort(); # 合并后排序
      l = len(t)
      medium = l//2 # 只取整数部分
      if l%2==1:
            return float(t) # 奇数直接返回中间
      else:
            return (t+t)/2.0 # 偶数返回前后相加除以2<precaa6f2c335818b0eeecaf13fba256a1bCode 3># 方法二class Solution:
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List
:type nums2: List
:rtype: float
"""
nums=[]
len1=len(nums1)
len2=len(nums2)
num1=num2=0
len0=len1+len2
for i in range(len0): # 遍历两个列表,实现拼接排序

      if(num1==len1):# 列表nums1遍历完
            nums.append(nums2)
            num2=num2+1
            continue
      if(num2==len2): # 列表nums2遍历完
            nums.append(nums1)
            num1=num1+1
            continue
      # 从小到大比较,小数先入 nums 列表
      if(nums1&lt;=nums2):
            nums.append(nums1)
            num1=num1+1
            continue
      else:
            nums.append(nums2)
            num2=num2+1
            continue
    if(len0 % 2 == 0):
      return (nums+nums)/2.0
    else:
      return nums<precaa6f2c335818b0eeecaf13fba256a1bCode 4>本方法引用自:https://www.jianshu.com/p/a2309fcdabfb
class Solution:
@param {integer[]} nums1

@param {integer[]} nums2

@return {float}

def findMedianSortedArrays(self, nums1, nums2):
l = len(nums1) + len(nums2)   # 总长度
if l % 2 == 1: # 奇数
a0 = self.findk(nums1, 0, len(nums1) - 1, nums2, 0, len(nums2) - 1, l // 2)
return a0
else: # 偶数
a0 = self.findk(nums1, 0, len(nums1) - 1, nums2, 0, len(nums2) - 1, l // 2)
b0 = self.findk(nums1, 0, len(nums1) - 1, nums2, 0, len(nums2) - 1, l // 2 - 1)
return (a0 + b0)/ 2.0</li>
</ul>
</blockquote>def findk(self, nums1, s1, e1, nums2, s2, e2, k):
"""
:type nums1: List,原列表1
:type nums2: List,原列表1
:type s1,s2: List,起始位置
:type e1,e2: List,终点位置
:type k: List,中位数下标+1
:rtype: float,结果
"""
if e1 - s1 < 0:   # 列表1为空

      return nums2
    if e2 - s2 &lt; 0:    # 列表2为空
      return nums1
    if k &lt; 1:   #两个列表一共只有一个元素
      return min(nums1, nums2)
    ia, ib = (s1 + e1) // 2 , (s2 + e2) // 2      # 列表中间数下标
    ma, mb = nums1, nums2   # 列表中间数数值
    if (ia - s1) + (ib - s2) &lt; k:
      if ma &gt; mb:
            return self.findk(nums1, s1, e1, nums2, ib + 1, e2, k - (ib - s2) - 1)
      else:
            return self.findk(nums1, ia + 1, e1, nums2, s2, e2, k - (ia - s1) - 1)
    else:
      if ma &gt; mb:
            return self.findk(nums1, s1, ia - 1, nums2, s2, e2, k)
      else:
            return self.findk(nums1, s1, e1, nums2, s2, ib - 1, k) <precaa6f2c335818b0eeecaf13fba256a1bCode 6>

[*]运行结果
页: [1]
查看完整版本: #yyds干货盘点#两个排序数组的中位数,“最”有技术含量的解法