【leetcode】Median of Two Sorted Arrays 如果觉得网上其他解释太难,那么请看这篇

Median of Two Sorted Arrays

这个题太难了,看到方法之后都不会编的那种,各种复杂,各种边界条件。

首先,要把这个问题转化为求两个有序数组中第K个数的问题;

求第K个数问题,关键是2分的时候把谁删除掉,网上的解法多少都有些晦涩难懂,这里面有一个“至多”,“至少”的问题,完整python代码如下,代码后面有解释:

class Solution:
    # @return a float
    def findMedianSortedArrays(self, A, B):
        m = len(A)
        n = len(B)
        if m == 0 and n == 0:
            return 0
        k = m + n
        if k % 2 == 0:
            return (self.find_kth(A, B, k/2) + float(self.find_kth(A, B, k/2+1)))/2
        else:
            return self.find_kth(A, B, k/2+1)
    
    def find_kth(self, A, B, k):
        m = len(A)
        n = len(B)
        if m == 0:
            return B[k-1]
        if n == 0:
            return A[k-1]
        i = m / 2
        j = n / 2
        if A[i] <= B[j]:
            p = A
            q = B
        else:
            p = B
            q = A
            i, j = j, i
        t = i + j + 1
        if k <= t:
            return self.find_kth(p, q[:j], k)
        else:
            return self.find_kth(p[i+1:], q, k - i - 1)

首先第一个函数很简单,调用找第k大的;主要看第二个函数,怎么找的第k大;

find_kth(self, A, B, k)

举个栗子:

A:[3, 5, 9, 10, 12, 15]

B:[1, 7, 10, 11, 15, 19, 22]

k:5

比较两个的中值,A[3]=10 和 B[3]=11, 发现A[3]<=B[3](如果发现A的中值>B的中值那么就调换A,B位置,主要是为了方便,也可以分开写),这个说明什么呢,非常关键,解决这个问题的核心所在:

说明了,B[3]前面至少有(3+3+1)=7个元素,B[3]至少是第(3+3+1)+1=8大,要么是并列(即便B[3]身处并列,即便是并列第一,那他前面也可以认为有7个),要么是第8,9,10,11...(因为A[3]右侧的也可能小于B[3]);

还说明了,A[3]至多是第(3+3+1)大,道理和上面一样,如果B[3]前面的也都小于A[3]那么,A[3]最大,是第七名;

为啥呢?怎么就说明了呢?

A[3] < =B[3], 那么:

(1)A[0-3]以及B[0-2]都是<=B[3],那么怎么着B[3]前面也会有7个元素,

(2)A[3]<=B[3],B[3]前面最多有7个元素,A[3]如果是紧挨着B[3]的,那么他也就是第7大,他不可能比A[4]之后的大

这样我们就有这么个知识了,A[3]至多第7大,B[3]至少第8大,然后去看K

因为k = 5:

 k <= 7,那么就说明,B[3]往后,连同B[3]都可以删除掉,肯定不是我们找的,我们找第5名的,那我们知道了B[3]至少第8,所以把B中B[3]往后(含B[3])的全部干死;

那如果k = 8呢:

k >7,那么就说明,A[3]往前,连同A[3]全部都可以删除到,肯定不是我们找的,我们找第8名,我们知道A[3]最多也就是第7,所以把A[3]之前(含A[3])全部干死;

然后进入递归;

A:[3, 5, 9, 10, 12, 15]

B:[1, 7, 10]

k:5

以此类推

需要注意的是,如果删掉的是A的前半部分,那么K的值也要相应更改,因为你想要找第9,删掉了3个最小的,在剩下的集合中,你就不是找第9了,而是找第6了;

还有就是递归结束条件是有一个数组长度为0了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值