昇順でソートされた2つの整数配列nums1とnums2と整数kが与えられます。
最初の配列の1つの要素と2番目の配列の1つの要素で構成されるペア(u、v)を定義します。
合計が最小のkペア(u1、v1)、(u2、v2)...(uk、vk)を見つけます。
例1:
入力:nums1 = [1,7,11]、nums2 = [2,4,6]、k = 3 出力:[[1,2]、[1,4]、[1,6]] 説明:最初のシーケンスから3つのペアが返されます: [1,2]、[1,4]、[1,6]、[7,2]、[7,4]、[11,2]、[7,6]、 [11,4]、[11,6]
例2:
入力:nums1 = [1,1,2]、nums2 = [1,2,3]、k = 2
出力:[1,1]、[1,1]
説明:最初の2つのペアがシーケンスから返されます:
[1,1]、[1,1]、[1,2]、[2,1]、[1,2]、[2,2]、[1,3]、[1,3]、[2 、3]
例3:
入力:nums1 = [1,2]、nums2 = [3]、k = 3 出力:[1,3]、[2,3] 説明:すべての可能なペアがシーケンスから返されます:[1,3]、[ 2,3]
重要な観察:Kペア&&最小。->ヒープ
最小ヒープソリューション。O(K * log K)ランタイム、O(K)スペース
1.ペアのインデックスを取得し、ペアの合計を比較する最小ヒープを作成します。
2.最初のMath.min(nums1.length、k)のペアをフォーマット(i、0)で追加して最小ヒープにします。iはnums1のインデックス、0はnums2の0インデックスを表します。
3.最小ヒープからポーリングし、回答するペアを追加してから、nums2インデックスを1増やした新しいペアを作成し、それを最小ヒープに追加します。
4. kペアになるか、最小ヒープにペアがなくなるまで、3を繰り返します。
このアルゴリズムのバリエーションは、最小ヒープ(0、0)のみを最小ヒープに追加することです。次に、ペアをポーリングするたびに、ペアの最初のインデックスを増やします。次に、ペアの2番目のインデックスを増やします。ただし、同じペアを2回以上追加しないようにするために、追加の簿記が必要になります。
クラスSolution { public List <List <Integer >> kSmallestPairs(int [] nums1、int [] nums2、int k){ List <List <Integer >> res = new ArrayList <> (); if(nums1.length == 0 || nums2.length == 0 ){ return res; } PriorityQueue < int []> minPq = new PriorityQueue <>((a、b)-> { return nums1 [a [0]] + nums2 [a [1]]-nums1 [b [0]]-nums2 [b [1 ]]; }); セットする<Integer> [] set = new Set [nums1.length]; for(int i = 0; i <nums1.length; i ++ ){ set [i] = new HashSet <> (); } minPq.add(new int [] {0、0 }); set [ 0] .add(0 ); while(k> 0 && minPq.size()> 0 ){ int [] curr = minPq.poll(); List <Integer> list = new ArrayList <> (); list.add(nums1 [curr [ 0 ]]); list.add(nums2 [curr [ 1 ]]); res.add(list); if(curr [0] <nums1.length-1 &&!set [curr [0] + 1] .contains(curr [1 ])){ minPq.add(new int [] {curr [0] + 1、curr [1 ]}); set [curr [ 0] + 1] .add(curr [1 ]); } if(curr [1] <nums2.length-1 &&!set [curr [0]]。contains(curr [1] + 1 )){ minPq.add(new int [] {curr [0]、curr [ 1] + 1 }); set [curr [ 0]]。add(curr [1] + 1 ); } K -; } 解像度を返す。 } }
関連する問題
[LeetCode 719] K番目に短いペアの距離を見つける