Find index of pair among given pairs with just greater average


In this problem, we will find the index value for each pair such that the resultant pair's average value is just greater than the current pair's average value.

To solve the problem, we will use the sorting algorithm and binary search technique. We will use a sorting algorithm to sort the array based on the pair's average value and a binary search algorithm to search a pair with a greater average value from the sorted array.

Problem Statement

We have given a pairs[] array containing the N pairs of positive integers. It is also given that the first element of each pair is distinct. We need to find the index value for each pair whose average is just greater than the current pair.

The average of {a, b} is floor((a + b)/2).

Sample Examples

Input –  pairs = {{1, 5}, {2, 3}, {3, 6}}
Output – 2 0 -1

Explanation

  • The average value of the {3, 6} is just greater than the {1, 5} pair's average value. So, it prints the index 2.

  • The average value of the {2, 3} is 2, and {1, 5} is 3. So, it prints the index 0.

  • There is not any pair exists whose average value is greater than {3, 6} pair's average value. So, it prints -1.

Input –  pairs = {{3, 2}, {2, 8}, {4, 6}, {1, 11}}
Output – 2 3 3 -1

Explanation

It can also be possible that the same index value can be the answer for multiple pairs.

Input –  pairs = {{1, 5}, {2, 4}, {3, 3}, {4, 2}};
Output – -1 -1 -1 -1

Explanation

When the average of all indexes is the same, it prints -1 for each index.

Approach 1

In this approach, we will use the sort() method and comparator to sort the given list of pairs based on the average value of the pair. After that, we will use the binary search for each pair to search for the index of the pair whose average value is just greater than the current pair's average value.

Algorithm

  • Step 1 − Define the 'indices' map to store the actual index of each pair.

  • Step 2 − Traverse the given list of pairs and map the index to the first element of the pair, as the first element of each pair is unique.

  • Step 3 − Use the sort() method to sort the list and pass the pairCompare() function as a third parameter. The pairComapre() function is a comparator function that returns true if the first pair's average value is less than or equal to the second pair's average value. Otherwise, it returns false.

  • Step 4 − Next, initialize the 'output' list to store the answer and start traversing the sorted list of pairs.

  • Step 5 − Take an average of the current pair, and pass it as a parameter of the getLowerBound() function to get the pair with just a greater average value.

  • Step 5.1 − In the getLowerBound() function, initialize the left and right pointers for the binary search and 'ind' with -1 to store the index value of the required pair.

  • Step 5.2 − Make traversal until the left is less than or equal to the right pointer. Take a middle index and the average value of the pair, which is at the middle index.

  • Step 5.3 − If the average value at the middle index is less than the target average, update left with middle + 1. Otherwise, update right with middle – 1 and 'ind' with the middle index.

  • Step 5.4 − When loop iterations are complete, if the 'ind' value is -1, return -1.

  • Step 5.5 − Take the pair's average value, which is at the 'ind' index. If the average is greater than the target average, return the 'ind' value. Otherwise, return -1.

  • Step 6 − If getLowerBound() returns -1, update the output list with -1 at the actual index of the current pair, which we can get from the indices map. Otherwise, update the output list with the resultant index value.

Example

#include <bits/stdc++.h>
using namespace std;

int getLowerBound(vector<pair<int, int>> pairs, int t_avg) {
   // Variables for binary search
   int left = 0, right = (int)pairs.size() - 1;
   int ind = -1;
   // Binary search algorithm
   while (left <= right) {
    
      // Get middle index
      int middle = (left + right) / 2;
        
      // Get the average of the middle index
      int avg = (pairs[middle].first + pairs[middle].second) / 2;
        
      // When the average is smaller than the target average
      if (avg <= t_avg)
         left = middle + 1;
      else {
        
         // When the average is larger than the target average
         right = middle - 1;
         ind = middle;
      }
   }

   if (ind == -1)
      return -1;

   // Take average of last found index
   int avg = (pairs[ind].first + pairs[ind].second) / 2;

   if (avg > t_avg)
      return ind;
   return -1;
}

bool pairCompare(pair<int, int> &m, pair<int, int> &n) {
   int first = (m.first + m.second) / 2;
   int second = (n.first + n.second) / 2;

   // Sort based on the average value
   return first <= second;
}

void getPairs(vector<pair<int, int>> &pairs, int len) {
   // To track indices and their average
   unordered_map<int, int> indices;

   // Map the first element of the pair and the current index
   for (int p = 0; p < len; p++) {
      indices[pairs[p].first] = p;
   }

   // Sort list based on the condition of comparators
   sort(pairs.begin(), pairs.end(), pairCompare);
   
   // To store output
   vector<int> output(len);
   for (int p = 0; p < len; p++) {
   
      // Get the average of the pair
      int avg = (pairs[p].first + pairs[p].second) / 2;
      
      // Get lower bound of pair
      int ind_val = getLowerBound(pairs, avg);
      
      // If the current pair has the largest average value
      if (ind_val == -1)
         output[indices[pairs[p].first]] = -1;
         
      // When we find the valid pair having just a greater average value than the current value
      else
         output[indices[pairs[p].first]] = indices[pairs[ind_val].first];
   }
   
   // Print the final array
   for (auto x : output)
      cout << x << ' ';
}

int main() {
   vector<pair<int, int>> pairs = {{1, 5}, {2, 3}, {3, 6}};
   int pairs_len = pairs.size();
   cout << "The indices according to the given condition are ";
   getPairs(pairs, pairs_len);
   return 0;
}

Output

The indices according to the given condition are 2 0 -1
  • Time Complexity − O(N*logN + logN), where O(NlogN) is for sorting the list and O(logN) is for searching the index value.

  • Space Complexity − O(N) to store the answer values.

We use the binary search algorithm to search the index with just a greater average value. However, programmers may use the linear search algorithm as, in most cases, the pair with just a greater average value will be next to the current pair.

Updated on: 05-Oct-2023

37 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements