4レコードLeetCodeアルゴリズムの問題 - 2つの注文の配列の中央値のための外観

タイトル

サイズとnums1 mおよびn nums2二順序付けられた配列を与え。

メジアンおよび整然とした配列の両方を検索し、アルゴリズムの時間複雑度はO(ログ(M + N))である必要があります。

あなたはnums1とnums2を想定し、両方の空にすることはできません。

例1:

nums1 = [1,3]
nums2 = [2]

中央値は2.0である
実施例2:

nums1 = [1、2]
nums2 = [3、4]

中央値は、(2 + 3)/ 2 = 2.5であります

出典:滞在ボタン(LeetCode)
リンクします。https://leetcode-cn.com/problems/median-of-two-sorted-arrays
すべてのネットワークからの控除が著作権を保有。商業転載は、ソースを明記してください許可公式、非商用の転載をご連絡ください。

ソリューション

LeetCodeユーザーから:待機ミス
この質問は、私たちは中央値2は、配列を命じたが、また、複雑さはO(ログ(M + n)は時間を制限聞いてみましょう 、) だと思う当然、今回の複雑さを見てあなたが解決するためにバイナリ検索を使用する必要があります。そして、規則配列の長さが奇数の場合には、偶数の2つの数の平均の中で最もある場合、中央値は、そのほとんどの真ん中で、中央値の定義を見て。ここでは、2つの配列の長さは、N Mとの2つの長さを仮定して順序付けられたアレイの2つの規則正しいアレイに対して同じであり、そしてm + nはパリティの不確実性、奇数のため、分割の場合を議論することが必要です、ほとんどの真ん中の2つの数の平均場合でも、要求のほとんど真ん中を見つける直接番号。コードを簡単にするために関係なく、議論の、我々は小さなトリックを使用して、我々は、それぞれを見つける(M + N + 1)/ 2 番目、及び(M + N + 2)/ 2 番目、及び平均を見つけるために、このパリティが適用されます。追加m + nは奇数であり、その後、実際には、(M + N + 1)の値/ 2(M + N + 2)/ 2は、同じ2つの同一の数の当量および2で割った、またはそれかどうかであります。

ここでは、2秩序配列、最初のK要素のフォーカスを見つける方法で、次の見の最初のKの要素を見つけるために、関数を定義する必要があります。まず、時間の複雑性を高めるために新しい配列を避けるために、我々は、i、jは、それぞれ2つの変数を使用し、nums2の配列nums1の開始位置をマークします。次に、境界の一部が、そのような配列の開始位置が同じである配列の特定の長さよりも大きい場合などの問題を処理するために、記載されているすべての数値は、空の配列の等価物は、次いで、効果的に、それは他のになり、消去されていますデジタルの配列を見つけ、あなたは見つけることができます指示します。K = 1は、その後、その後、私たちは、iとjのnums2その上に開始位置にnums1と数字を比較する場合、あります。一般的な状況に対処する方法の難しさのうそ?我々は、規則的な配列でK要素のうちの2つを見つけるの検索を高速化するためにする必要があるため、我々は最初のK / 2の要素を見つけるnums1とnums2内にある必要があることを意味K-半分の二分法を、使用したいです注による不確かさの2つの配列の長さに、私たちは確認する必要があるので、存在しないK / 2桁の端部にアレイを維持し、K / 2桁のアレイの可能性がないこと、取り出すべき存在する場合、そうでない場合は最大の整数に割り当て。アレイは、第一K / 2桁の数字でない場合は、我々は別の番号に前者K / 2桁を除去します。この質問に、K 2列/それの2桁が存在しないことが可能であることは、我々がKに任意ないので、不可能であるが、中間の値にm + nは、少なくともなければなりませんK / 2桁の配列の存在があります。最後に二分法は、小型の最初のK / 2桁の最初の配列ならば、我々はデジタルを探していることを確認してください2/2 midVal1少数とK-配列midVal2の大きさを比較し、問題の核心であります前者は、我々は排除することができるように後方番目、移動開始位置nums1のK / 2 nums1 K / 2桁ではなく、この時点でKはまた、再帰的に呼び出さK / 2、から減算されます。逆に、我々は、フロントnums2のK / 2桁を除去し、後方にK / 2開始位置nums2を移動し、KもK / 2から減算し、この時点で、再帰的に呼び出すことができました。

class Solution {
  public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        int left = (m + n + 1) / 2;
        int right = (m + n + 2) / 2;
        return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;
    }
    //i: nums1的起始位置 j: nums2的起始位置
    public int findKth(int[] nums1, int i, int[] nums2, int j, int k){
        if( i >= nums1.length) return nums2[j + k - 1];//nums1为空数组
        if( j >= nums2.length) return nums1[i + k - 1];//nums2为空数组
        if(k == 1){
            return Math.min(nums1[i], nums2[j]);
        }
        int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE;
        int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE;
        if(midVal1 < midVal2){
            return findKth(nums1, i + k / 2, nums2, j , k - k / 2);
        }else{
            return findKth(nums1, i, nums2, j + k / 2 , k - k / 2);
        }        
    }
}
发布了2 篇原创文章 · 获赞 0 · 访问量 100

おすすめ

転載: blog.csdn.net/qq_44310853/article/details/104106796