Processing math: 100%

Monday, April 9, 2018

K Smallest Sum Pairs

REFERENCE @ LeetCode

RELATED PROBLEM  Kth Smallest Numer in Sorted Matrix

Task Description

Given two integer arrays nums1 and nums1 sorted in non-decreasing order and an integer k.

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

Find k pairs with smallest sums.

Solution 1 : Brute Force Solution

The naive solution would be to find all possible pairs and find the best k pairs from it. If the two array contain n and m items, then there are nm possible pairs. Retrieving k best pairs will take θ(klog(mn)) time.

Solution 2: Efficient Solution

This Brute Force solution can be optimized by using Priority Queue. The Priority Queue will hold sequence of number pairs (i, j) where i is index in the first array and j is that in the second array. Priority of the queue is determined by the sum of numbers at these indices.


  PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>(){
      @Override
      public int compare(int[] a, int[] b) {
          return nums1[a[0]] + nums2[a[1]] - nums1[b[0]] - nums2[b[1]];
      }
  });

    
Initially, for i = 0, all pairs with the second array is inserted into the priority queue. At this time, the first priority element is minimum element.

  for (int i = 0; i < nums2.length; i++) {
      queue.offer(new int[]{0, i});
  }

    
Then we keep on polling an element from the queue and insert into the result. For each poll, we will insert into the queue, i+1 pairing with its corresponding unpaired index so far in the second array. This is repeated untill the queue is not empty or untill we have all the k pairs required.

  while(!queue.isEmpty() && res.size() < k) {
      int[] item = queue.poll();
      res.add(new int[]{nums1[item[0]], nums2[item[1]]});
      
      if (item[0] == nums1.length - 1) {
          continue;
      } else {
          queue.offer(new int[]{item[0] + 1, item[1]});
      }
  }

    

Full Code


    public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        List<int[]> res = new ArrayList<int[]>();
        PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>(){
            @Override
            public int compare(int[] a, int[] b) {
                return nums1[a[0]] + nums2[a[1]] - nums1[b[0]] - nums2[b[1]];
            }
        });
        
        if(nums1.length == 0 || nums2.length == 0) {
            return res;
        }
        
        for (int i = 0; i < nums2.length; i++) {
            queue.offer(new int[]{0, i});
        }
        
        while(!queue.isEmpty() && res.size() < k) {
            int[] item = queue.poll();
            res.add(new int[]{nums1[item[0]], nums2[item[1]]});
            
            if (item[0] == nums1.length - 1) {
                continue;
            } else {
                queue.offer(new int[]{item[0] + 1, item[1]});
            }
        }
    
        return res;
    }

    

Time Complexity

Initial insertion into the priority queue takes O(m) time. During the iteration, for each minimum element polled from the queue, we insert at maximum only one element, hence the size of the queue is maintained O(m) and each iteration take O(log(m)) time. The iteration is repeated untill we have all the k results or the queue is empty. Overall Time complexity is O(klog(m))O(klog(n)). The space complexity is O(n) for the size of priority queue.






No comments:

Post a Comment