尋找兩個有序陣列的中值
1. 演算法描述
有兩個陣列 A 和 B,均為有序排列,A的長度為m,B的長度為n,求 A 和 B 合在一起後的中值.
2. 問題分析
- 這裡要注意一下:要充分利用 A和B均為有序的特性
- 該問題進一步可轉化為求A和B的任意K值,如三分位、四分位.
思路一:將A和B合併成新的陣列
- /**
- * 合併有序陣列,然後尋找K值
- *
- * @param a
- * 有序陣列a
- * @param b
- * 有序陣列b
- * @param k
- * k值位置,0<=k<=a.length+b.length-1
- * @return k值
- */
- publicstaticint findKthByMerge(int[] a, int[] b, int k) {
- System.out.println("Find kth by merge array first");
- int[] ab = newint[a.length + b.length];
- int ai = 0, bi = 0, abi = 0;
- while (ai < a.length && bi < b.length) {
- ab[abi++] = (a[ai] < b[bi]) ? a[ai++] : b[bi++];
- }
- while (ai < a.length) {
- ab[abi++] = a[ai++];
- }
- while (bi < b.length) {
- ab[abi++] = b[bi++];
- }
- System.out.println(Arrays.toString(ab));
- return ab[k];
- }
這種方法最容易想到,合併成有序陣列後即可求任意k值,其時間複雜度為 O(m+n), 空間複雜圖為O(m+n)
這裡反思一下:真的需要合併陣列嗎?
思路二:採用掃描計數方法
- /**
- * 無需合併陣列,利用計數機尋找K值
- *
- * @param a
- * 有序陣列a
- * @param b
- * 有序陣列b
- * @param k
- * k值位置,0<=k<=a.length+b.length-1,k同時充當計數器
- * @return k值
- */
- publicstaticint findKthByCounter(int[] a, int[] b, int k) {
- System.out.println("Find kth by counter");
- int ai = 0, bi = 0;
- int kth = 0; // 儲存K值
- while (ai < a.length && bi < b.length && k >= 0) {
- kth = (a[ai] < b[bi]) ? a[ai++] : b[bi++];
- k--;
- }
- while (ai < a.length && k >= 0) {
- kth = a[ai++];
- k--;
- }
- while (bi < b.length && k >= 0) {
- kth = b[bi++];
- k--;
- }
- return kth;
- }
本演算法是對演算法一的改進,用一個臨時變數儲存K值,而不需要講新合併的陣列單獨儲存,節省了儲存空間。
其 時間複雜度為O(m+n), 空間複雜度為O(1).
到此都是線性時間複雜度,已經是非常高效了,但又沒有更加高效的方法進一步降低時間複雜度呢?
這裡注意到原陣列有序特性,利用二分特性可以將複雜度降至對數級別。
思路三:遞迴二分
- /**
- * 遞迴二分查詢K值
- *
- * @param a
- * 有序陣列a
- * @param b
- * 有序陣列b
- * @param k
- * K值位置,0<=k<=m+n-1
- * @param aStart
- * 陣列a初始查詢位置
- * @param aEnd
- * 陣列a結束查詢位置
- * @param bStart
- * 陣列b初始查詢位置
- * @param bEnd
- * 陣列b結束查詢位置
- * @return k值
- */
- publicstaticint findKth(int a[], int b[], int k, int aStart, int aEnd,
- int bStart, int bEnd) {
- int aLen = aEnd - aStart + 1;
- int bLen = bEnd - bStart + 1;
- // 遞迴結束條件
- if (aLen == 0) {
- return b[bStart + k];
- }
- if (bLen == 0) {
- return a[aStart + k];
- }
- if (k == 0) {
- return a[aStart] < b[bStart] ? a[aStart] : b[bStart];
- }
- // 將k按比例分配到a和b中,(k+1)=ka+kb,
- int ka = (k + 1) * aLen / (aLen + bLen);
- int kb = (k + 1) - ka;
- ka += aStart;
- kb += bStart;
- // 因為a和b有序,aStart-ka , bStart-kb yi
- <span style="white-space:pre;"> </span>// 最大值進行比較
- if (a[ka] > b[kb]) {
- k = k - (kb - bStart); // bStart - kb 這段應當排除,調整k值
- aEnd = ka; // 新k值可能存在於 aStart - ka
- bStart = kb; // 新k值可能存在於 kb - bEnd 之間
- } else {
- k = k - (ka - aStart);
- bEnd = kb;
- aStart = ka;
- }
- return findKth(a, b, k, aStart, aEnd, bStart, bEnd);
- }
3. 測試演算法
-
相關推薦
Algorithm 04 : 尋找兩個有序陣列中的第N個數,要求時間複雜度為O(logm+logn)
Question : Give a divide and conquer algorithm for the following problem : you are given two sorted lists of size m and n
尋找兩個有序陣列的中值
1. 演算法描述有兩個陣列 A 和 B,均為有序排列,A的長度為m,B的長度為n,求 A 和 B 合在一起後的中值.2. 問題分析這裡要注意一下:要充分利用 A和B均為有序的特性該問題進一步可轉化為求A和B的任意K值,如三分位、四分位.思路一:將A和B合併成新的陣列/**
LeetCode之4. 尋找兩個有序陣列的中位數
LeetCode之4. 尋找兩個有序陣列的中位數 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你可以假設 nums1 和 nums2 不會同時為空。
leetcode演算法題4: 尋找兩個有序陣列的中位數
題目:給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你可以假設 nums1 和 nums2 不會
Leetcode(4)尋找兩個有序陣列的中位數
題目描述 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你可以假設 nums1 和 nums2 不會同時為空。 示例 1: nums1 = [1, 3] nums2 = [2]
尋找兩個有序陣列的中位數-- leetCode
尋找兩個有序陣列的中位數 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你可以假設 nums1 和 nums2 不會同時為空。 示例 1: nums1 =
尋找兩個有序陣列的中位數
題目:給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你
LeetCode演算法4:java 尋找兩個有序陣列的中位數
題目描述 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你可以假設 nums1 和 nums2 不會同時為空。 示例 1: nums1 = [1, 3] n
4. 尋找兩個有序陣列的中位數(python3)
Python3: class Solution: def findMedianSortedArrays(self, nums1, nums2): """ :type nums1: List[int] :type nums2: L
尋找兩個有序陣列的中位數(LeetCode)
想法如下: 當數的個數為奇數時,中位數就這一堆已經排好序的數最中間那一個 當數的個數為偶數時,中位數就是中間那兩個數的平均數 class Solution: def findMedianSortedArrays(self, nums1, nums2): &nb
Leetcode 4. Median of Two Sorted Arrays 尋找兩個有序陣列的中位數
Leetcode 4. Median of Two Sorted Arrays 尋找兩個有序陣列的中位數 標籤: Leetcode 題目地址:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 題目
leetcode(2)尋找兩個有序陣列的中位數的js實現
一.題目描述: 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你可以假設 nums1 和 nums2 不會同時為空。 示例 1: nums1 = [1, 3
leetcode | Median of Two Sorted Arrays 尋找2個有序陣列中第k大的值
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time
【分步詳解】兩個有序陣列中的中位數和Top K問題
問題介紹 這是個超級超級經典的分治演算法!!這個問題大致是說,如何在給定的兩個有序數組裡面找其中的中值,或者變形問題,如何在2個有序陣列陣列中查詢Top K的值(Top K的問題可以轉換成求第
Java實現O(log(n+m))兩個有序陣列中第K大元素或中位數
假設有兩個從小到大的有序陣列A和B,他們的元素個數為N和M,那麼怎麼求得其第K大元素呢?同理,求其中位數就是當N+M為奇數求其第(N+M+1)/2大元素,為偶數時求(N+M)/2和(N+M+2)/2大元素的平均值。 那麼我們怎麼才能求得第K大元素呢? 分別取兩個陣列中間索
(分治演算法)兩個有序陣列中的中位數和Top K問題
問題介紹 這是個超級超級經典的分治演算法!!這個問題大致是說,如何在給定的兩個有序數組裡面找其中的中值,或者變形問題,如何在2個有序陣列陣列中查詢Top K的值(Top K的問題可以轉換成求第k個元素的問題)。這個演算法在很多實際應用中都會用到,特別是在當前大資料的
兩個有序陣列中位數
大小m和n分別有兩個排序陣列A和B。找到兩個排序陣列的中值。總的執行時間複雜度應該是O(log(m+n))。class Solution { public: /** * @param A: An integer array. * @param
資料結構演算法題/兩個有序陣列的中位數
有三種方法,時間複雜度分別是O(m+n) ,O(k),O(log(m+n)) 注意點: 判斷合併後的陣列的元素個數是奇數還是偶數 如果是奇數取中間值;如果是偶數取中間2個數的平均值。 兩種求中位數的方法: (1)方法1,判斷奇數個還是偶數個 if (lengthall % 2 == 0)
【死磕演算法之1刷Leetcode】——找出兩個有序陣列的中位數【Median of Two Sorted Arrays】O(log(m+n))
Median of Two Sorted Arrays 題目難度:hard 題目要求: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two s
leetcode第四題:兩個有序陣列的中位數
給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。 你可以假設 nums1 和 nums2 不會同時為空。 示例