leetcode 4. Median of Two Sorted Arrays(二分查找)

1.分析问题:

这里有两点条件,长度相等,任意元素大于。所以列出下面的模型,为了后面便于思考

             left_part | right_part lee

A[0], A[1], …, A[i-1] | A[i], A[i+1], …, A[m-1]

B[0], B[1], …, B[j-1] | B[j], B[j+1], …, B[n-1]

其中

m:A数组长度

n:B数组长度

i:A数组的分割点,一共有m+1个分割点,i=0,1,2…m

j:B数组的分割点,一共有n+1个分割点,j=0,1,2…n

2.找出判断条件:

根据中位数的性质,得出判断条件为:

(1) len(left_part) == len(right_part)

(2) max(left_part) <= min(right_part)

首先设置n>=m,原因如下:

即设置数组A为长度较小的数组。如果数组A的长度大于数组B的长度,A的分割点无法到取到靠后的位置,因为可能会使leftA的长度大于rightA+lenB的长度。这样i就可以任意取,i , j 结果都为正,我们只要考虑 i的范围即可,有序数组的查找显然后面可以使用二分法。

继续推导判断条件,有两种情况:

<1> 当m+n为偶数时,中位数是中间两数之和,若想找到正确的i,应该有:

     (1) i + j == m - i + n - j 

     (2) B[j-1] <= A[i] and A[i-1] <= B[j]

最后的结果为 (max(A[i-1], B[j-1]) + min(A[i], B[j]))/2

<2> 当m+n为奇数时,中位数是中间的一个数,把中间的数归到左半部分,则有:

     (1) i + j == m - i + n - j + 1

     (2) B[j-1] <= A[i] and A[i-1] <= B[j]

这时最后的结果为 max(A[i-1], B[j-1])

我们之前设置过i是可以任意取值的,于是有j=(m+n)/2-i,并且其中j > 0。

当m+n为偶数时,(m+n)/2==(m+n+1)/2,所以以上两种情况的判断条件可以合并,但两种情况的中位数结果是不同的,于是得到最终判断条件为:

      (1) i = 0 ~ m, j = (m + n + 1)/2 - i 

      (2) B[j-1] <= A[i] and A[i-1] <= B[j]

3.确定循环过程:

根据上面的特点,可以对i使用二分法查找,并且根据之前对奇偶情况结果的讨论,需要保存left_part_max和right_part_min。

设置imin=0,imax=m,i=(imin+imax)/2,则对于一个给定的i,有如下几种情况:

搜索过程:

<1> B[j-1] > A[i] && i < m , 需要增加i,令imin=i+1

<2> A[i-1] > B[j] && i > 0 , 需要减小i,令imax=i-1

备注:(i小于m时,因为m<=n,j若等于0,右半部分元素会过多,所以j一定大于0)

       (i大于0时,因为m<=n,j若等于n,左半部分元素会过多,所以j一定小于n)

之后判断各边界位置的情况来得到leftmax和righmin

代码如下:
class Solution {
public:
double findMedianSortedArrays(vector& nums1, vector& nums2) {

    int m=nums1.size();
    int n=nums2.size();
    if(m>n)
    {
        return findMedianSortedArrays(nums2,nums1);
    } 
    
    int imin=0;
    int imax=m;
    int amount=(m+n+1)/2;
    while(imin<=imax)
    {
        int i=(imin+imax)/2;
        int j=amount-i;
        if(i<m&&nums1[i]<nums2[j-1])
        {
            imin=i+1;
        }
        else if(i>0&&nums2[j]<nums1[i-1])
        {
            imax=i-1;
        }
        else
        {
            int leftmax;
            if(i==0)
            {
                leftmax=nums2[j-1];
            }
            else if(j==0)
            {
                leftmax=nums1[i-1];
            }
            else leftmax=max(nums2[j-1],nums1[i-1]);
            if((n+m)%2==1)
            {
                return leftmax;
            }
            int rightmin;
            if(i==m)
            {
               rightmin=nums2[j];   
            }
            else if(j==n)
            {
                rightmin=nums1[i];
            }
            else rightmin=min(nums1[i],nums2[j]);
              return (rightmin+leftmax)/2.0;
            
        }
    }
    return 0;
}

};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值