zoukankan      html  css  js  c++  java
  • 有序矩阵中的第 k 个最小数组和

    给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。

    你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。

    示例 1:

    输入:mat = [[1,3,11],[2,4,6]], k = 5

    输出:7

    解释:从每一行中选出一个元素,前 k 个和最小的数组分别是:

    [1,2], [1,4], [3,2], [3,4], [1,6]。其中第 5 个的和是 7 。  

    示例 2:

    输入:mat = [[1,3,11],[2,4,6]], k = 9

    输出:17

    示例 3:

    输入:mat = [[1,10,10],[1,4,5],[2,3,6]], k = 7

    输出:9

    解释:从每一行中选出一个元素,前 k 个和最小的数组分别是:

    [1,1,2], [1,1,3], [1,4,2], [1,4,3], [1,1,6], [1,5,2], [1,5,3]。其中第 7 个的和是 9 。 

    示例 4:

    输入:mat = [[1,1,10],[2,2,9]], k = 7

    输出:12

    说明:

    m ,n为矩阵 mat的行列数

    1 <= m, n <= 40

    1 <= k <= min(200, n ^ m)

    1 <= mat[i][j] <= 5000

    mat[i] 是一个非递减数组

    输入说明 :

    首先输入矩阵mat的行列数m和n

    然后输入m行,每行n个非负整数,表示mat的元素值,以空格分隔。

    最后输入k。

    输出说明 :

    输出一个整数,表示结果。

    输入范例 :

    2 3
    1 3 11
    2 4 6
    5

    输出范例 :

     7

     1 #include<iostream>
     2 #include<map>
     3 #include<queue>
     4 #include<set>
     5 #include<vector>
     6 #include<algorithm>
     7 using namespace std;
     8 class Solution {
     9 public:
    10     //使用小顶堆 小顶堆中存储每列选的元素的坐标和加和
    11     //每次将最小的取出 当第k次取时即为答案
    12     //每次取出后 被选的元素的坐标依次加一
    13     struct Cell
    14     {
    15         int sum;
    16         vector<int> indexs;
    17         Cell(int _sum, vector<int>_v) :sum(_sum), indexs(_v) {};
    18         bool operator <(const Cell& c)const
    19         {
    20             return sum > c.sum;
    21         }
    22     };
    23     int kthSmallest(vector<vector<int>>& mat, int k) {
    24         priority_queue<Cell> pq;
    25         int n = mat.size(), m = mat[0].size();
    26         vector<int> indexs(n, 0);
    27         int sum = 0;
    28         for (int i = 0; i < n; i++)sum += mat[i][0];
    29         set<vector<int>> indexs_set;
    30         indexs_set.insert(indexs);
    31         pq.push({ sum, indexs });
    32         while (k--)
    33         {
    34             Cell c = pq.top();
    35             if (!k)return c.sum;
    36             pq.pop();
    37             for (int i = 0; i < n; i++)
    38             {
    39                 indexs.assign( c.indexs.begin(),c.indexs.end());
    40                 if (indexs[i] + 1 < m)
    41                 {
    42                     indexs[i] += 1;
    43                     if (indexs_set.find(indexs) == indexs_set.end())
    44                     {
    45                         pq.push({ c.sum - mat[i][indexs[i] - 1] + mat[i][indexs[i]],indexs });
    46                         indexs_set.insert(indexs);
    47                     }  
    48                 }
    49             }
    50         }
    51         return 0;
    52     }
    53     //动态规划 使用一个数组last_row记录之前所有的行 的最小数组和
    54     //然后使用新增加的行的每一个值 都加上last_row的值 然后排序 取前k个
    55     //o(n(mk+mklogmk))
    56     /*int kthSmallest(vector<vector<int>>& mat, int k) {
    57         vector<int> last_row = { 0 };
    58         vector<int> temp_row;
    59         for (int i = 0; i < mat.size(); i++)
    60         {
    61            // print_v(last_row);
    62             for (int j = 0; j < mat[0].size(); j++)
    63             {
    64                 for (int p = 0; p < last_row.size(); p++)
    65                 {
    66                     temp_row.push_back(last_row[p] + mat[i][j]);
    67                 }
    68             }
    69             sort(temp_row.begin(),temp_row.end());
    70             //print_v(temp_row);
    71             if (temp_row.size() > k)
    72                 last_row.assign(temp_row.begin(), temp_row.begin() + k);
    73             else
    74                 last_row.assign(temp_row.begin(), temp_row.end());
    75             temp_row.resize(0);
    76         }
    77         return last_row[k - 1];
    78     }*/
    79 };
    80 int main()
    81 {
    82     int m, n, data, k;
    83     vector<vector<int> > mat;
    84     cin >> m >> n;
    85     for (int i = 0; i < m; i++)
    86     {
    87         vector<int> row;
    88         for (int j = 0; j < n; j++)
    89         {
    90             cin >> data;
    91             row.push_back(data);
    92         }
    93         mat.push_back(row);
    94     }
    95     cin >> k;
    96     int res = Solution().kthSmallest(mat, k);
    97     cout << res << endl;
    98     return 0;
    99 }
  • 相关阅读:
    AJ学IOS 之微博项目实战(10)微博cell中图片的显示以及各种填充模式简介
    AJ学IOS 之微博项目实战(9)微博模型之时间相关重要操作,判断刚刚,昨天,今年等等
    AJ学IOS 之控制器view显示中view的父子关系及controller的父子关系_解决屏幕旋转不能传递事件问题
    AJ学IOS 之UIDynamic重力、弹性碰撞吸附等现象
    AJ学IOS 之CoreLocation反地理编码小Demo输入经纬度得到城市
    AJ学IOS 之CoreLocation地理编码小Demo输入城市得到经纬度
    AJ学IOS 之CoreLocation指南针小应用
    AJ学IOS 之CoreLocation基本使用
    AJ学IOS 之第一次打开Xcode_git配置,git简单学习
    AJ学IOS 之微博项目实战(8)用AFNetworking和SDWebImage简单加载微博数据
  • 原文地址:https://www.cnblogs.com/lancelee98/p/13263000.html
Copyright © 2011-2022 走看看