angular2做的网站有设计风格网站欣赏
news/
2025/10/5 22:29:08/
文章来源:
angular2做的网站有,设计风格网站欣赏,做网站好,阿里云服务器租用多少钱一年文章目录 1. 题目2. 思路及代码实现#xff08;Python#xff09;2.1 二分查找2.2 划分数组 1. 题目
给定两个大小分别为 m m m 和 n n n 的正序#xff08;从小到大#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为… 文章目录 1. 题目2. 思路及代码实现Python2.1 二分查找2.2 划分数组 1. 题目
给定两个大小分别为 m m m 和 n n n 的正序从小到大数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O ( l o g ( m n ) ) O(log(mn)) O(log(mn))。
示例 1
输入nums1 [1,3], nums2 [2] 输出2.00000 解释合并数组 [1,2,3] 中位数 2
示例 2
输入nums1 [1,2], nums2 [3,4] 输出2.50000 解释合并数组 [1,2,3,4] 中位数 (2 3) / 2 2.5 提示 n u m s 1. l e n g t h m nums1.length m nums1.lengthm n u m s 2. l e n g t h n nums2.length n nums2.lengthn 0 m 1000 0 m 1000 0m1000 0 n 1000 0 n 1000 0n1000 1 m n 2000 1 m n 2000 1mn2000 − 1 0 6 n u m s 1 [ i ] , n u m s 2 [ i ] 1 0 6 -10^6 nums1[i], nums2[i] 10^6 −106nums1[i],nums2[i]106
2. 思路及代码实现Python
2.1 二分查找
对于查找两个数组的中位数我们很自然想到中位数的寻找方式就是将数组由小到大排序然后根据数组长度计算出中位数的索引位置找到相应位置的数即可。现在的问题是对于拆成两部分的数组我们如何找到合并后的数组的某个索引位置的值呢
一个简单的方式是直接把两个数组按顺序合并成一个大数组进行索引这个过程的时间复杂度为 O ( m n ) O(mn) O(mn)空间复杂度也为 O ( m n ) O(mn) O(mn)由于题目给出的两个数组本身就是有序的因此还有另一个直观的方法是对两个数组分别各维护一个指针共同移动指针的过程判断是否到达中位数的索引位置该方法的时间复杂度为 O ( m n ) O(mn) O(mn)空间复杂度为 O ( 1 ) O(1) O(1)。然而题目要求的是让时间复杂度降为 O ( l o g ( m n ) ) O(log(mn)) O(log(mn))这相当于就是明示需要用到二分查找之类的方法。
基于上述的逻辑我们其实根据索引值就能找到中位数的值因此二分查找用在如何加快搜索该索引值下的值上已知有两个数组长度分别为 m , n m,n m,n若 m n mn mn 是奇数则中位数的索引为 ( m n ) / / 2 (mn)//2 (mn)//2若为偶数则中位数取索引为 ( m n ) / / 2 , ( m n ) / / 2 1 (mn)//2, (mn)//21 (mn)//2,(mn)//21的两个数的平均值。那如何加速搜索第 k k ( m n ) / / 2 或 k ( m n ) / / 2 1 kk(mn)//2 或 k(mn)//21 kk(mn)//2或k(mn)//21 个值呢就需要利用到两个数组也都是有序的这个特点。当我们在已知两数组长度后计算得到 k k k 值然后想办法将 k k k 拆开用以每次比较能排除 k / 2 k/2 k/2 的值因此我们需要每次比较两个数组的索引为 k / 2 − 1 k/2-1 k/2−1 的值这样当比较小的值的那方涉及到的 k / 2 k/2 k/2 个值可以被一次排除。存在特殊边界条件当 k 1 k1 k1说明要查找的是两个数组中最小的数取两个数组首元素进行比较即可。
class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) - float:def getKthElement(k):index1, index2 0, 0while True:# 特殊情况if index1 m:return nums2[index2 k - 1]if index2 n:return nums1[index1 k - 1]if k 1:return min(nums1[index1], nums2[index2])# 正常情况newIndex1 min(index1 k // 2 - 1, m - 1)newIndex2 min(index2 k // 2 - 1, n - 1)pivot1, pivot2 nums1[newIndex1], nums2[newIndex2]if pivot1 pivot2:k - newIndex1 - index1 1index1 newIndex1 1else:k - newIndex2 - index2 1index2 newIndex2 1m, n len(nums1), len(nums2)totalLength m nif totalLength % 2 1:return getKthElement((totalLength 1) // 2)else:return (getKthElement(totalLength // 2) getKthElement(totalLength // 2 1)) / 2执行用时44 ms 消耗内存17.11 MB
参考来源力扣官方题解
2.2 划分数组
上一个方法通过两个数组的长度计算出中位数的索引通过维护两个指针来不断更新中位数的索引最终找到中位数。另一个方法是划分数组我们知道当 m n mn mn 为偶数时可以将两个数组的数值划分为长度相等的两部分其中数值较小部分的最大值不大于数值较大部分的最小值同理若 m n mn mn 长度为奇数则较小部分的长度比较大部分长度多1哪边多1都一样中位数就是较小部分数组中的最大值。
举个例子 [ 2 , 4 , 5 , 7 , 9 , 11 ] [2,4,5,7,9,11] [2,4,5,7,9,11]在这个数组中长度为偶数可以分为 [ 2 , 4 , 5 ] , [ 7 , 9 , 11 ] [2,4,5], [7,9,11] [2,4,5],[7,9,11] 两个数组而左边数组的最大值不大于右边数组的最小值。因此现在题目中有两个数组假设为 A , B A,B A,B长度分别为 m , n m,n m,n则可以通过 0 ≤ i ≤ m 0\leq i\leq m 0≤i≤m将 A A A分为两部分 A [ 0 ] , A [ 1 ] , . . . A [ i − 1 ] 和 A [ i ] , . . . , A [ m − 1 ] A[0],A[1],...A[i-1]和A[i],...,A[m-1] A[0],A[1],...A[i−1]和A[i],...,A[m−1]同理通过 j j j 也可以将 B B B分成两部分 B [ 0 ] , B [ 1 ] , . . . B [ j − 1 ] 和 B [ j ] , . . . , B [ n − 1 ] B[0],B[1],...B[j-1]和B[j],...,B[n-1] B[0],B[1],...B[j−1]和B[j],...,B[n−1]其中若 m n mn mn 为偶数则 i j ( m n ) / 2 ij(mn)/2 ij(mn)/2若为奇数则 i j ( m n 1 ) / 2 ij(mn1)/2 ij(mn1)/2。因此在已知两个数组长度时确定了 i i i 的值即可确定 j j j 的值。这里有个小坑就是我们以 i i i 去计算 j j j 的值时需保证 ( m n ) / 2 或者 ( m n 1 ) / 2 减 i (mn)/2或者(mn1)/2减i (mn)/2或者(mn1)/2减i的值要大于等于0因此需要保证 m ≤ n m\leq n m≤n如果 n ≤ m n\leq m n≤m则调换一下位置即可。
关键的地方来了当我们遍历 A A A 的值时 i i i 递增 j j j 会递减我们总能找到一个使得 A [ i − 1 ] ≤ B [ j ] A[i-1]\leq B[j] A[i−1]≤B[j]的最大的 i i i此时由于 i i i 是临界值所以 A [ i ] B [ j ] A[i] \gt B[j] A[i]B[j]且 B [ j ] ≥ B [ j − 1 ] B[j] \geq B[j-1] B[j]≥B[j−1]所以我们只需搜索 m m m找到满足 A [ i − 1 ] ≤ B [ j ] A[i-1]\leq B[j] A[i−1]≤B[j] 的最大 i i i 即可这个搜索过程可以用二分搜索进一步加速。
class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) - float:if len(nums1) len(nums2):return self.findMedianSortedArrays(nums2, nums1)infinty 2**40m, n len(nums1), len(nums2)left, right 0, m# median1前一部分的最大值# median2后一部分的最小值median1, median2 0, 0while left right:# 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]# // 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]i (left right) // 2j (m n 1) // 2 - i# nums_im1, nums_i, nums_jm1, nums_j 分别表示 nums1[i-1], nums1[i], nums2[j-1], nums2[j]nums_im1 (-infinty if i 0 else nums1[i - 1])nums_i (infinty if i m else nums1[i])nums_jm1 (-infinty if j 0 else nums2[j - 1])nums_j (infinty if j n else nums2[j])if nums_im1 nums_j:median1, median2 max(nums_im1, nums_jm1), min(nums_i, nums_j)left i 1else:right i - 1return (median1 median2) / 2 if (m n) % 2 0 else median1执行用时40 ms 消耗内存17.14 MB
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/928799.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!