C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++のKリストからの最小範囲カバー要素


ソートされた整数のリストがk個あるとします。 k個のリストのそれぞれから少なくとも1つの数字を含む最小の範囲を検索する必要があります。ここで、範囲[a、b]は、b-a

したがって、入力が[[4,10,15,25,26]、[0,9,14,20]、[5,18,24,30]]の場合、出力は[14、18]になります。

これを解決するには、次の手順に従います-

  • minRange:=inf、maxRange:=-inf、rangeSize:=inf、tempMinRange:=inf、tempMaxRange:=-inf
  • n:=numsのサイズ
  • サイズnの配列ポインタを定義します
  • 優先キューpqを作成する
  • iを初期化する場合:=0、i
  • {nums [i、0]、i}をpqに挿入します
  • tempMaxRange:=tempMaxRangeとnums[i、0]の最大値
  • 1がゼロ以外の場合は、-
      を実行します。
    • 1ペアの温度を定義します:=pqの上部
    • pqから要素を削除する
    • tempMinRange:=temp.first
    • idx:=tempの2番目の要素
    • tempMaxRange − tempMinRange
    • rangeSize:=tempMaxRange --tempMinRange
    • minRange:=tempMinRange
    • maxRange:=tempMaxRange
  • (pointers [idx]を1増やします)
  • pointers[idx]がnums[idx]のサイズと同じである場合、-
    • ループから抜け出す
  • それ以外の場合
    • tempMaxRange:=tempMaxRangeとnums[idx、pointers [idx]]
    • の最大値
    • {nums [idx、pointers [idx]]、idx}をpqに挿入します
  • サイズ2の配列を定義します
  • ans [0]:=minRange、ans [1]:=maxRange
  • 回答を返す
  • 理解を深めるために、次の実装を見てみましょう-

    #include <bits/stdc++.h>
    using namespace std;
    void print_vector(vector<auto> v){
       cout << "[";
       for(int i = 0; i<v.size(); i++){
          cout << v[i] << ", ";
       }
       cout << "]"<<endl;
    }
    struct Comparator{
       bool operator() (pair <int, int> a, pair <int, int> b){
          return !(a.first < b.first);
       }
    };
    class Solution {
    public:
       vector<int> smallestRange(vector<vector<int>>& nums) {
          int minRange = INT_MAX;
          int maxRange = INT_MIN;
          int rangeSize = INT_MAX;
          int tempMinRange, tempMaxRange, tempRangeSize;
          tempMinRange = INT_MAX;
          tempMaxRange = INT_MIN;
          int n = nums.size();
          vector <int> pointers(n);
          priority_queue < pair <int, int>, vector < pair <int, int> >, Comparator > pq;
          for(int i = 0; i < n; i++){
             pq.push({nums[i][0], i});
             tempMaxRange = max(tempMaxRange, nums[i][0]);
          }
          while(1){
             pair <int, int> temp = pq.top();
             pq.pop();
             tempMinRange = temp.first;
             int idx = temp.second;
             if(tempMaxRange - tempMinRange < rangeSize){
                rangeSize = tempMaxRange - tempMinRange;
                minRange = tempMinRange;
                maxRange = tempMaxRange;
             }
             pointers[idx]++;
             if(pointers[idx] == nums[idx].size())break;
             else{
                tempMaxRange = max(tempMaxRange, nums[idx][pointers[idx]]);
                pq.push({nums[idx][pointers[idx]], idx});
             }
          }
          vector <int> ans(2);
          ans[0] = minRange;
          ans[1] = maxRange;
          return ans;
       }
    };
    main(){
       Solution ob;
       vector<vector<int>> v = {{4,10,15,25,26},{0,9,14,20},{5,18,24,30}};
       print_vector(ob.smallestRange(v));
    }

    入力

    {{4,10,15,25,26},{0,9,14,20},{5,18,24,30}};

    出力

    [14, 18, ]

    1. 範囲合計クエリ-C++の不変

      整数の配列があるとします。インデックスiからjまでの要素の合計を見つける必要があります。配列は不変であるため、要素は変更されず、そのようなクエリが複数存在することに注意する必要があります。そのため、多数のクエリの実行時間を気にする必要があります。配列がA=[5、8、3、6、1、2、5]のようであるとすると、クエリが(A、0、3)の場合、5 + 8 + 3 + 6=22になります。 これを解決するには、次の手順に従います- 1つの配列Bを取得します。B[i]は0からiまでの要素の合計を格納します クエリの場合は、B [j] – B [i – 1]を実行します 理解を深めるために、次の実装

    2. C++で指定された3つのソートされた配列から最も近い3つの要素を検索します

      max(| A [i] – B [i] |、| B [j] – Cのように、3つのソートされた配列A、B、Cと、それぞれA、B、Cからの3つの要素i、j、kがあるとします。 [k] |、| C [k] – A [i] |)が最小化されます。したがって、A =[1、4、10]、B =[2、15、20]、およびC =[10、12]の場合、出力要素は10、15、10、これら3つはA、B、およびCからのものです。 A、B、Cのサイズがそれぞれp、q、rであるとします。次に、次の手順に従ってこれを解決します- i:=0、j:=0およびk:=0 ここで、i