LeetCode_Everyday:004 Median of Two Sorted Arrays

LeetCode_Everyday:004 Median of Two Sorted Arrays


LeetCode Everyday:堅持價值投資,做時間的朋友!!!

題目:

給定兩個大小爲 m 和 n 的正序(從小到大)數組 nums1nums2
請你找出這兩個正序數組的中位數,並且要求算法的時間複雜度爲 O(log(m + n))。
你可以假設 nums1nums2 不會同時爲空。

示例:

  • 示例 1
    nums1 = [1, 3]
    nums2 = [2]
    則中位數是 2.0
    
  • 示例 2
    nums1 = [1, 2]
    nums2 = [3, 4]
    則中位數是 (2 + 3)/2 = 2.5
    

代碼

方法一: 暴力法,合併兩個數組,進行排序,然後求中位數。

Tips:  這種方法時間複雜度取決於排序方法,可以參考我的一些筆記 快速排序O((m+n)log(m+n))O((m+n)log(m+n))
    本題的話時間複雜度不滿足要求,只提供思路,另外,之所以編譯通過,是因爲驗證集合維度過小。
    另外python默認排序算法是Timesort算法wikiCSDN博客翻譯

執行用時 :60 ms, 在所有 Python3 提交中擊敗了47.66%的用戶
內存消耗 :13.9 MB, 在所有 Python3 提交中擊敗了6.15%的用戶

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """   
        nums = nums1 + nums2
        nums.sort()
        i = len(nums) // 2
        j = len(nums) // 2 - int(len(nums) % 2 == 0)
        return (nums[i] + nums[j]) / 2

"""
For Example:    input:   nums1 = [1, 2]   nums2 = [3, 4]
               output:   2.0
"""

nums1 = [1, 2]
nums2 = [3, 4]
                
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('輸出爲:', result)  # 2.5

方法二: 建立雙指針,歸併排序的思路

Tips:需要注意的是循環終止條件不需要遍歷所有值,找到需要的即可。
   時間複雜度是O(m+n2)=O(m+n)O(\frac{m+n}{2})=O(m+n),不滿足本題要求,只提供思路。

執行用時 :68 ms, 在所有 Python3 提交中擊敗了26.49%的用戶
內存消耗 :13.9 MB, 在所有 Python3 提交中擊敗了6.15%的用戶

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """   
        len1 = len(nums1)
        len2 = len(nums2)
        length = len1 + len2     
        p1 = 0
        p2 = 0
        r = []
        while (len(r) < (length // 2 + 1)):
            if (p1 == len1):
                r.append(nums2[p2])
                p2 = p2 + 1
            elif (p2 == len2):
                r.append(nums1[p1])
                p1 = p1 + 1
            else:
                if (nums1[p1] < nums2[p2]):
                    r.append(nums1[p1])
                    p1 = p1 + 1
                else:
                    r.append(nums2[p2])
                    p2 = p2 + 1
                    
        f = 1 if (length%2 == 0) else 0
        if f == 0:
            return r[length//2]
        else:
            return (r[length//2]+r[length//2-1])/2

"""
For Example:    input:   nums1 = [1, 2]   nums2 = [3, 4]
               output:   2.0
"""

nums1 = [1, 2]
nums2 = [3, 4]
                
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('輸出爲:', result)   # 2.5

方法三: 二分查找的思路。時間複雜度O(log(m+n))O(log(m+n)),滿足題意。題注

執行用時 :52 ms, 在所有 Python3 提交中擊敗了78.70%的用戶
內存消耗 :13.7 MB, 在所有 Python3 提交中擊敗了6.15%的用戶

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """   
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2, nums1
        len1, len2 = len(nums1), len(nums2)
        
        left, right, half_len = 0, len1, (len1 + len2 + 1) // 2
        mid1 = (left + right) // 2
        mid2 = half_len - mid1
        
        while left < right:
            if mid1 < len1 and nums2[mid2-1] > nums1[mid1]:
                left = mid1 + 1
            else:
                right = mid1
            mid1 = (left + right) // 2
            mid2 = half_len - mid1
        
        if mid1 == 0: 
            max_of_left = nums2[mid2-1]
        elif mid2 == 0: 
            max_of_left = nums1[mid1-1]
        else: 
            max_of_left = max(nums1[mid1-1], nums2[mid2-1])

        if (len1 + len2) % 2 == 1:
            return max_of_left
        if mid1 == len1: 
            min_of_right = nums2[mid2]
        elif mid2 == len2: 
            min_of_right = nums1[mid1]
        else: 
            min_of_right = min(nums1[mid1], nums2[mid2])
        
        return (max_of_left + min_of_right) / 2

"""
For Example:    input:   nums1 = [1, 2]   nums2 = [3, 4]
               output:   2.0
"""

nums1 = [1, 2]
nums2 = [3, 4]
                
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('輸出爲:', result)   # 2.5

方法四: 尋找第k小的思路。時間複雜度O(log(m+n))O(log(m+n)),滿足題意。題注

執行用時 :52 ms, 在所有 Python3 提交中擊敗了78.70%的用戶
內存消耗 :13.8 MB, 在所有 Python3 提交中擊敗了6.15%的用戶

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """   
        m, n = len(nums1), len(nums2)
        total = m + n
        if total & 1:
            return self.findKth(nums1, m, nums2, n, total//2 + 1)
        else:
            return (self.findKth(nums1, m, nums2, n, total//2) + \
                   self.findKth(nums1, m, nums2, n, total//2 + 1))/2

    def findKth(self, nums1, m, nums2, n, k):
        if m > n:
            return self.findKth(nums2, n, nums1, m, k)
        if m == 0:
            return nums2[k-1]
        if k == 1:
            return min(nums1[0], nums2[0])
        p1 = min(k //2, m)
        p2 = k - p1
        if nums1[p1-1] < nums2[p2-1]:
            return self.findKth(nums1[p1:], m - p1, nums2, n, k-p1)
        elif nums1[p1-1] > nums2[p2-1]:
            return self.findKth(nums1, m, nums2[p2:], n - p2, k-p2)
        else:
            return nums1[p1-1]

"""
For Example:    input:   nums1 = [1, 2]   nums2 = [3, 4]
               output:   2.0
"""

nums1 = [1, 2]
nums2 = [3, 4]
                
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('輸出爲:', result)   # 2.5

圖解:

引用的圖片展示的是方法三的部分思路,可以幫助分析,很不錯,圖片不顯示可以去參考1自行查看。

參考

  1. https://github.com/MisterBooo/LeetCodeAnimation
  2. https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/dong-yong-er-fen-cha-zhao-mo-ban-lai-qiao-miao-jie/
  3. https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/di-k-xiao-shu-jie-fa-ni-zhen-de-dong-ma-by-geek-8m/
  4. https://www.bilibili.com/video/BV1d7411Q7GR

此外

  • 原創內容轉載請註明出處
  • 請到我的GitHub點點 star
  • 關注我的 CSDN博客
  • 關注公衆號:CV伴讀社

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章