373. Find K Pairs with Smallest Sums

You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.

Define a pair (u,v) which consists of one element from the first array and one element from the second array.

Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.

Example 1:

Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
Output: [[1,2],[1,4],[1,6]] 
Explanation: The first 3 pairs are returned from the sequence: 
             [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]

Example 2:

Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
Output: [1,1],[1,1]
Explanation: The first 2 pairs are returned from the sequence: 
             [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]

Example 3:

Input: nums1 = [1,2], nums2 = [3], k = 3
Output: [1,3],[2,3]
Explanation: All possible pairs are returned from the sequence: [1,3],[2,3]
 

There are three ways to solve this problem, in approach #1(this is my own code) I use a vector to stroe the pair of nums1[i] and nums2[2] then sorting the vector. The time complex: O(N*M)

In approach #2, we use a struct of priority_queue to store the pair, this is the complete explaction.

In approach #3, we use bfs to search the minimum element from left-top to right-bottom. this is the complete explaction.

 

Approach #1: C++.[brute force]

class Solution {
public:
    vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
        vector<pair<int, int>> temp;
        for (int i = 0; i < nums1.size(); ++i) {
            for (int j = 0; j < nums2.size(); ++j) {
                temp.push_back({nums1[i], nums2[j]});
            }
        }
        sort(temp.begin(), temp.end(), cmp); 
        
        vector<pair<int, int>> ans;
        for (int i = 0; i < temp.size() && i < k; ++i) {
            ans.push_back(temp[i]);
        }
        
        return ans;
    }
    
private:
    static bool cmp(pair<int, int> a, pair<int, int> b) {
        return a.first + a.second < b.first + b.second;
    }
};

  

Approach #2: Java.

class Solution {
    public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        PriorityQueue<int[]> que = new PriorityQueue<>((a, b)->a[0]+a[1]-b[0]-b[1]);
        List<int[]> res = new ArrayList<>();
        if (nums1.length == 0 || nums2.length == 0 || k == 0) return res;
        for (int i = 0; i < nums1.length && i < k; i++) 
            que.offer(new int[]{nums1[i], nums2[0], 0});
        while (k-- > 0 && !que.isEmpty()) {
            int[] cur = que.poll();
            res.add(new int[]{cur[0], cur[1]});
            if (cur[2] == nums2.length-1) continue;
            que.offer(new int[]{cur[0], nums2[cur[2]+1], cur[2]+1});
        }
        return res;
    }
}

  

Approach #3: Python.

class Solution(object):
    def kSmallestPairs(self, nums1, nums2, k):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :type k: int
        :rtype: List[List[int]]
        """
        import heapq
        ret = []
        if len(nums1) * len(nums2) > 0:
            queue = [(nums1[0] + nums2[0], (0, 0))]
            visited = {}
            while len(ret) < k and queue:
                _, (i, j) = heapq.heappop(queue)
                ret.append((nums1[i], nums2[j]))
                if j + 1 < len(nums2) and (i, j+1) not in visited:
                    heapq.heappush(queue, (nums1[i] + nums2[j+1], (i, j+1)))
                    visited[(i, j+1)] = 1
                if i + 1 < len(nums1) and (i+1, j) not in visited:
                    heapq.heappush(queue, (nums1[i+1] + nums1[j], (i+1, j)))
                    visited[(i+1, j)] = 1
        return ret

  

 

posted @ 2018-12-19 20:42  Veritas_des_Liberty  阅读(239)  评论(0编辑  收藏  举报