寻找两个正序数组的中位数(python)

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。


题目分析:

这道题目需要我们在两个有序数组中,查找它们的中位数。中位数是指将一个集合元素按大小排列后,形成的一个数值序列中最中间的那个数。对于偶数个元素的序列,它没有唯一的中间值,而是取最中间的两个元素的算术平均数。

解决方案:

1.将两个有序数组进行切分,使得两个部分的长度差不超过 1。

2.使得切分后两个部分左侧的所有元素都小于右侧的所有元素。

3.根据两个部分左侧的元素个数之和判断中位数应该在哪一部分。

4.如果两个部分长度之和为奇数,则中位数为左侧部分最大的元素;如果长度为偶数,则需要取左侧最大元素和右侧最小元素的平均值作为中位数。

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        # 将较长的数组定义为 nums1
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2, nums1
            
        m, n = len(nums1), len(nums2)
        left, right, half_len = 0, m, (m + n + 1) // 2
        
        while left <= right:
            i = (left + right) // 2
            j = half_len - i
            if i < m and nums2[j-1] > nums1[i]:
                # i 偏小,需要右移
                left = i + 1
            elif i > 0 and nums1[i-1] > nums2[j]:
                # i 偏大,需要左移
                right = i - 1
            else:
                # i 长度刚好
                if i == 0:
                    max_of_left = nums2[j-1]
                elif j == 0:
                    max_of_left = nums1[i-1]
                else:
                    max_of_left = max(nums1[i-1], nums2[j-1])
                
                if (m + n) % 2 == 1:
                    return max_of_left
                
                if i == m:
                    min_of_right = nums2[j]
                elif j == n:
                    min_of_right = nums1[i]
                else:
                    min_of_right = min(nums1[i], nums2[j])
                    
                return (max_of_left + min_of_right) / 2.0

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

 KMP解法:

这道题目是一道字符串匹配问题,给出一个字符串和一个模式串,在字符串中查找是否存在符合模式串的子串。

为了解决这个问题,我们也可以采用经典的 KMP 算法来实现。KMP 算法是一个高效的字符串匹配算法,它的核心思想是通过利用已知信息来跳过不必要的匹配,从而达到提高匹配效率的目的。

1.我们首先根据模式串构建 next 数组,其中 next[i] 表示当遇到第 i 个字符不匹配时,下一个匹配位置应该在模式串中的哪个位置上。

2.然后我们使用双指针的方法来进行匹配,将 i 指针指向字符串中待匹配的下一个位置,将 j 指针指向模式串中待匹配的下一个位置。

3.如果当前字符匹配成功,则将 i 和 j 都向一下个位置移动一位;否则,根据 next 数组中已保存的信息,计算 j 指针的下一个位置,继续进行匹配。

4.直到匹配成功或者字符串中的字符已经全部遍历成功为止。

时间复杂度为 O(m + n),其中 m 表示字符串的长度,n 表示模式串的长度。

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if not needle:
            return 0
        
        m, n = len(haystack), len(needle)
        next = self.get_next(needle)
        i, j = 0, 0
        
        while i < m and j < n:
            if j == -1 or haystack[i] == needle[j]:
                i += 1
                j += 1
            else:
                j = next[j]
            
        if j == n:
            return i - j
        
        return -1
        
    def get_next(self, needle):
        n = len(needle)
        next = [-1] * n
        i, j = 0, -1
        
        while i < n - 1:
            if j == -1 or needle[i] == needle[j]:
                i += 1
                j += 1
                next[i] = j
            else:
                j = next[j]
                
        return next

 时间复杂度为 O(m + n),运行时间为 36 ms,内存消耗为 14.7 MB,可以 AC 这道题目。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值