You are given an m x n matrix mat that has its rows sorted in non-decreasing order and an integer k.

You are allowed to choose exactly one element from each row to form an array.

Return the kth smallest array sum among all possible arrays.

&nbsp;
Example 1:

Input: mat = [[1,3,11],[2,4,6]], k = 5
Output: 7
Explanation: Choosing one element from each row, the first k smallest sum are:
[1,2], [1,4], [3,2], [3,4], [1,6]. Where the 5th sum is 7.


Example 2:

Input: mat = [[1,3,11],[2,4,6]], k = 9
Output: 17


Example 3:

Input: mat = [[1,10,10],[1,4,5],[2,3,6]], k = 7
Output: 9
Explanation: Choosing one element from each row, the first k smallest sum are:
[1,1,2], [1,1,3], [1,4,2], [1,4,3], [1,1,6], [1,5,2], [1,5,3]. Where the 7th sum is 9.  


&nbsp;
Constraints:


	m == mat.length
	n == mat.length[i]
	1 &lt;= m, n &lt;= 40
	1 &lt;= mat[i][j] &lt;= 5000
	1 &lt;= k &lt;= min(200, nm)
	mat[i] is a non-decreasing array.


class Solution:
    def kthSmallest(self, mat: List[List[int]], k: int) -> int:
        def kSmallestPairs(nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:
            h = [(nums1[0]+nums2[0],0,0)]
            visited = set()
            res = []
            while h and k > 0:
                e, i, j = heappop(h)
                if (i,j) in visited: continue
                res.append(e)
                visited.add((i,j))
                if j+1 < len(nums2):
                    heappush(h,(nums1[i]+nums2[j+1],i,j+1))
                if i+1 < len(nums1):
                    heappush(h,(nums1[i+1]+nums2[j],i+1,j))
                k -= 1
            return res
        res = mat[0]
        for i in range(1, len(mat)):
            res = kSmallestPairs(res, mat[i], k)
        return res[-1]
class Solution {
    public int kthSmallest(int[][] mat, int k) {
        int[] row = mat[0];
        
        for(int i=1; i<mat.length; i++) {
            row = findKthSmallest(row, mat[i], k);
        }
        
        return row[k-1];
    }
    
    private int[] findKthSmallest(int[] num1, int[] num2, int k) {
        List<Integer> list = new ArrayList<>();
        PriorityQueue<int[]> minHeap = new PriorityQueue<>((a,b) -> (a[0]+a[1]) - (b[0]+b[1]));
        
        for(int i=0; i<num1.length && i<k; i++) {
            minHeap.offer(new int[]{num1[i], num2[0], 0});
        }
        
        for(int i=0; i<k && !minHeap.isEmpty(); i++) {
            int[] candidate = minHeap.poll();
            list.add(candidate[0] + candidate[1]); // SUM;
            int num2Idx = candidate[2];
            
            if(num2Idx<num2.length-1) {
                minHeap.offer(new int[]{candidate[0], num2[num2Idx+1], num2Idx+1});
            }
        }
        
        return list.stream().mapToInt(i->i).toArray();
    }
}
class Solution {
public:
vector<int> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
        auto cmp = [&nums1,&nums2](pair<int,int> a, pair<int,int>b){
            return nums1[a.first]+nums2[a.second] >
                nums1[b.first]+nums2[b.second];
        };
        int n = nums1.size();
        int m = nums2.size();
        vector<int> ans;
        if(n==0 || m==0)
            return ans;
        priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(cmp)>pq(cmp);
        pq.push({0,0});
        while(k-- && !pq.empty())
        {
            int i = pq.top().first;
            int j = pq.top().second;
            pq.pop();
            
            if(j+1<m)
                pq.push({i,j+1});
            if(j==0 && i+1 <n)
                pq.push({i+1,j});
            
            ans.push_back(nums1[i]+nums2[j]);
        }
        return ans;
    }
    int kthSmallest(vector<vector<int>>& mat, int k) {
        vector<int> nums1 = mat[0];
        int n =  mat.size();
        for(int i = 1; i<n; ++i)
        {
            nums1 = kSmallestPairs(nums1,mat[i],k);
        }
        return nums1[k-1];
    }
};
/**
 * @param {number[][]} mat
 * @param {number} k
 * @return {number}
 */
var kthSmallest = function(mat, k) {
    var m = mat.length;
    var n = m ? mat[0].length : 0;
    if (!m || !n) return -1;
    var sums = [0];
    for (var idx = 0; idx < m; idx++) {
        var newSums = []
        for (var sum of sums) {
            for (var i = 0; i < n && i < k; i++) {
                var newSum = sum + mat[idx][i];
                if (newSums.length < k) {
                    newSums.push(newSum);
                } else if (newSum < newSums[k-1]) {
                    newSums.pop();
                    newSums.push(newSum);
                } else {
                    break;
                }
                newSums.sort((a, b) => a - b);
            }
        }
        sums = newSums;
    }
    return sums[k-1];
};
Find the Kth Smallest Sum of a Matrix With Sorted Rows