leetcode hot100 寻找两个正序数组的中位数 hard 二分查找 双指针


中位数本质

  1. 把序列分为左右两半,左右两半元素个数相等,或者左边多1
  2. 左边的数 < 右边的数

暴力解法

clike 复制代码
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:

        #nums=nums1.append(nums2)
        # 使用 + 号连接两个列表,这会返回一个新的列表
        nums = nums1 + nums2
        nums.sort()

        total = len(nums1) + len(nums2)

        if total %2 ==0:  # 偶数
            return (nums[total//2] + nums[total//2 -1]) / 2
        else:
            return nums[total//2]
        

合并排序后取中位数

时间复杂度 O(m+n), 不符合题目 O(log (m+n)) 要求


双指针计数法,不需要真的合并

线性扫描 → 时间复杂度 O(m+n),空间复杂度O(1)

把指针推进到总数一半位置

clike 复制代码
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:

        # 模拟 merge(归并两个有序数组),只走到中位数位置,时间复杂度O(m+n)

        m = len(nums1)
        n = len(nums2)
        total = m + n

        p1 = p2 = 0   # 双指针
        curr = 0  # 当前值(初值是啥没关系,会被覆盖)

        # 5个数的中位数是第3个,4个数的中位数是第2,3个,所以要走到total // 2 + 1
        for i in range(total // 2 + 1):

            prev = curr # 每次移动前,先保存上一次的结果prev

            # 谁小移动谁
            if p1 < m:  # 如果 nums1 还没走完
                if p2 >= n:             # 情况 A:nums2 走完了,只剩下nums1
                    curr = nums1[p1]
                    p1 += 1
                elif nums1[p1] <= nums2[p2]:  # 情况 B:还有nums2,但是nums1值更小
                    curr = nums1[p1]
                    p1 += 1
                else:                     # 情况 C:还有nums2,而且nums2值更小
                    curr = nums2[p2]
                    p2 += 1
            
            # 如果 nums1 走完了,只能拿 nums2 的
            else:
                curr = nums2[p2]
                p2 += 1 

        if total % 2 == 1:          # 如果总数是奇数,返回 curr
            return float(curr)
        else:
            return (prev + curr) / 2.0   # 如果总数是偶数,返回 (prev + curr) / 2

时间复杂度O(log (m+n))

相关推荐
superior tigre4 小时前
78 子集
算法·leetcode·深度优先·回溯
superior tigre6 小时前
739 每日温度
算法·leetcode·职场和发展
6Hzlia6 小时前
【Hot 100 刷题计划】 LeetCode 15. 三数之和 | C++ 排序+双指针
c++·算法·leetcode
北顾笙9808 小时前
day37-数据结构力扣
数据结构·算法·leetcode
6Hzlia10 小时前
【Hot 100 刷题计划】 LeetCode 189. 轮转数组 | C++ 三次反转经典魔法 (O(1) 空间)
c++·算法·leetcode
m0_6294947311 小时前
LeetCode 热题 100-----13.最大子数组和
数据结构·算法·leetcode
田梓燊11 小时前
力扣:94.二叉树的中序遍历
数据结构·算法·leetcode
khalil102011 小时前
代码随想录算法训练营Day-38动态规划06 | 322. 零钱兑换、279.完全平方数、139.单词拆分、多重背包、总结
数据结构·c++·算法·leetcode·动态规划
阿Y加油吧11 小时前
二刷 LeetCode:300. 最长递增子序列 & 152. 乘积最大子数组 复盘笔记
笔记·算法·leetcode