Open In App

Minimum swaps so that binary search can be applied

Last Updated : 23 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an unsorted array of length n and an integer k, find the minimum swaps to get the position of k before using the binary search. Here we can swap any two numbers as many times as we want. If we cannot get the position by swapping elements, print “-1”.
Examples: 

Input : arr = {3, 10, 6, 7, 2, 5, 4}
        k = 4
Output : 2
Explanation :
Here, after swapping 3 with 7 and 2 with 5, the 
final array will look like {7, 10, 6, 3, 5, 2, 4}.
Now, if we provide this array to binary search we
can get the position of 4.

Input : arr = {3, 10, 6, 7, 2, 5, 4}
        k = 10
Output : -1
Explanation :
Here, we can not get the position of 10 if we 
provide this array to the binary search even 
not with swapping some pairs.

Approach: Before discussing the approach, we have to assume that here we are not supposed to swap the pairs. We just need to count the minimum number of swaps so that if we provide the newly created array to the binary search, we can get the position of k. In order to do so, we need to pass the given array to binary search and focus on the following things:-  

  • Before going to the binary search we need to calculate the number of minimum elements i.e. num_min of k and the number of maximum elements i.e. num_max of k. Here, num_min denotes the number of smaller available elements of k and num_max denotes the number of greater available elements that we can use for swapping
  • The actual position of k in the given array.

Now following are the test cases that will occur during implementing the binary search:-
Case 1: If arr[mid] is greater than k, but the position of k is greater than mid. Binary search would take us to (arr[0] to arr[mid-1]). But actually our element is in between (arr[mid+1] to arr[last element]). So, in order to go in the right direction, we need something smaller than k so that we can swap it with arr[mid] and we can go between arr[mid+1] to arr[last_element]. So, here we require one swap i.e. need_minimum.
Case 2: If arr[mid] is less than k but the position of k is smaller than mid. Binary search would take us to (arr[mid+1] to arr[last_element]). But actually our element is in between (arr[0] to arr[mid-1]). So, in order to go in the right direction, we need something greater than k so that we can swap it with arr[mid] and we can go between arr[0] to arr[mid-1]. So, here we required one swap i.e. need_maximum.
Case 3: 
If arr[mid] is greater than k and the position of k is lesser than mid. Now, in this case, the binary search would work fine. But wait, here is the important thing on which we have to work on. As we know in this case binary search will work fine, arr[mid] is at the right position so this will not be used in any swap so here we have to decrease one of its greater available elements i.e. from num_max. The same goes with the case when arr[mid] is lesser than k and the position of k is greater than mid. Here, we have to decrease one of its smaller available elements i.e. from num_min.
Case 4: If arr[mid] == k Or pos == mid then we can easily come out from the binary search.
So, till now we have calculated the need_minimum i.e. number of minimum elements required for swapping, need_maximum i.e. number of maximum elements required for swapping, num_max i.e. a total number of greater elements from k that are still available for swapping, and num_min i.e. the total number of minimum elements from k that are available for swapping.
Now here we have to consider two cases: 
Case 1: If need_minimum is greater than need_maximum. In this case, we have to swap all these needed maximum elements with the smaller of k. So we have to use the smaller elements from num_min. Now all the need_maximum swaps are done. Here the main thing is that when we swapped all these needed maximum elements with smaller elements, these smaller elements got their right positions. So, indirectly we have done some of the needed smaller elements swaps and that will be calculated as need_minimum – need_maximum and also available num_min will be num_min – need_maximum. Now, we have to calculate the remaining need_minimum swaps. We can calculate these swaps if we have enough num_min i.e. num_min > need_minimum. For this case, swaps will be need_maximum + need_minimum otherwise it will be -1. The same concept goes with the case when we have need_minimum is smaller than need_maximum.
Below is the basic implementation of the above approach:-
 

C++




// CPP program to find Minimum number
// of swaps to get the position of
// the element if we provide an
// unsorted array to binary search.
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum swaps.
int findMinimumSwaps(int* arr, int n,
                     int k)
{
    int pos, num_min, num_max,
    need_minimum, need_maximum, swaps;
    num_min = num_max = need_minimum = 0;
    need_maximum = swaps = 0;
 
    // Here we are getting number of
    // smaller and greater elements of k.
    for (int i = 0; i < n; i++) {
        if (arr[i] < k)
            num_min++;
 
        else if (arr[i] > k)
            num_max++;
    }
 
    // Here we are calculating the actual
    // position of k in the array.
    for (int i = 0; i < n; i++) {
        if (arr[i] == k) {
            pos = i;
            break;
        }
    }
 
    int left, right, mid;
    left = 0;
    right = n - 1;
 
    // Implementing binary search as
    // per the above-discussed cases.
    while (left <= right) {
        mid = (left + right) / 2;
 
        // If we find the k.
        if (arr[mid] == k) {
            break;
        }
 
        else if (arr[mid] > k) {
 
            // If we need minimum
            // element swap.
            if (pos > mid)
                need_minimum++;
 
            else
 
                // Else the element is
                // at the right position.
                num_min--;
 
            left = mid + 1;
        }
 
        else {
            if (pos < mid)
 
                // If we need maximum
                // element swap.
                need_maximum++;
 
            else
 
                // Else element is at
                // the right position
                num_max--;
 
            right = mid - 1;
        }
    }
 
    // Calculating the required swaps.
    if (need_minimum > need_maximum) {
        swaps = swaps + need_maximum;
        num_min = num_min - need_maximum;
        need_minimum = need_minimum - need_maximum;
        need_maximum = 0;
    }
 
    else {
        swaps = swaps + need_minimum;
        num_max = num_max - need_minimum;
        need_maximum = need_maximum - need_minimum;
        need_minimum = 0;
    }
 
    // If it is impossible.
    if (need_maximum > num_max || need_minimum > num_min)
        return -1;
 
    else
        return (swaps + need_maximum + need_minimum);
}
 
// Driver function
int main()
{
    int arr[] = { 3, 10, 6, 7, 2, 5, 4 }, k = 4;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << findMinimumSwaps(arr, n, k);
}


Java




//Java program to find Minimum number
// of swaps to get the position of
// the element if we provide an
// unsorted array to binary search.
public class GFG {
 
// Function to find minimum swaps.
    static int findMinimumSwaps(int[] arr, int n,
            int k) {
        int pos = 0, num_min, num_max,
                need_minimum, need_maximum, swaps;
        num_min = num_max = need_minimum = 0;
        need_maximum = swaps = 0;
 
        // Here we are getting number of
        // smaller and greater elements of k.
        for (int i = 0; i < n; i++) {
            if (arr[i] < k) {
                num_min++;
            } else if (arr[i] > k) {
                num_max++;
            }
        }
 
        // Here we are calculating the actual
        // position of k in the array.
        for (int i = 0; i < n; i++) {
            if (arr[i] == k) {
                pos = i;
                break;
            }
        }
 
        int left, right, mid;
        left = 0;
        right = n - 1;
 
        // Implementing binary search as
        // per the above-discussed cases.
        while (left <= right) {
            mid = (left + right) / 2;
 
            // If we find the k.
            if (arr[mid] == k) {
                break;
            } else if (arr[mid] > k) {
 
                // If we need minimum
                // element swap.
                if (pos > mid) {
                    need_minimum++;
                } else // Else the element is
                // at the right position.
                {
                    num_min--;
                }
 
                left = mid + 1;
            } else {
                if (pos < mid) // If we need maximum
                // element swap.
                {
                    need_maximum++;
                } else // Else element is at
                // the right position
                {
                    num_max--;
                }
 
                right = mid - 1;
            }
        }
 
        // Calculating the required swaps.
        if (need_minimum > need_maximum) {
            swaps = swaps + need_maximum;
            num_min = num_min - need_maximum;
            need_minimum = need_minimum - need_maximum;
            need_maximum = 0;
        } else {
            swaps = swaps + need_minimum;
            num_max = num_max - need_minimum;
            need_maximum = need_maximum - need_minimum;
            need_minimum = 0;
        }
 
        // If it is impossible.
        if (need_maximum > num_max || need_minimum > num_min) {
            return -1;
        } else {
            return (swaps + need_maximum + need_minimum);
        }
    }
 
// Driver function
    public static void main(String[] args) {
 
        int arr[] = {3, 10, 6, 7, 2, 5, 4}, k = 4;
        int n = arr.length;
        System.out.println(findMinimumSwaps(arr, n, k));
    }
 
}
 
/*This code is contributed by PrinciRaj1992*/


Python3




# Python3 program to find Minimum number
# of swaps to get the position of
# the element if we provide an
# unsorted array to binary search.
 
# Function to find minimum swaps.
def findMinimumSwaps(arr,
                     n, k):
 
    num_min = num_max = need_minimum = 0
    need_maximum = swaps = 0
 
    # Here we are getting number of
    # smaller and greater elements of k.
    for i in range(n):
        if (arr[i] < k):
            num_min += 1
 
        elif (arr[i] > k):
            num_max += 1
 
    # Here we are calculating the actual
    # position of k in the array.
    for i in range(n):
        if (arr[i] == k):
            pos = i
            break
 
    left = 0
    right = n - 1
 
    # Implementing binary search as
    # per the above-discussed cases.
    while (left <= right):
        mid = (left + right) // 2
 
        # If we find the k.
        if (arr[mid] == k):
            break
 
        elif (arr[mid] > k):
            # If we need minimum
            # element swap.
            if (pos > mid):
                need_minimum += 1
 
            else:
 
                # Else the element is
                # at the right position.
                num_min -= 1
 
            left = mid + 1
 
        else:
            if (pos < mid):
 
                # If we need maximum
                # element swap.
                need_maximum += 1
 
            else:
 
                # Else element is at
                # the right position
                num_max -= 1
 
            right = mid - 1
 
    # Calculating the required swaps.
    if (need_minimum > need_maximum):
        swaps = swaps + need_maximum
        num_min = num_min - need_maximum
        need_minimum = (need_minimum -
                        need_maximum)
        need_maximum = 0
 
    else:
        swaps = swaps + need_minimum
        num_max = num_max - need_minimum
        need_maximum = (need_maximum -
                        need_minimum)
        need_minimum = 0
 
    # If it is impossible.
    if (need_maximum > num_max or
        need_minimum > num_min):
        return -1
 
    else:
        return (swaps + need_maximum +
                need_minimum)
 
# Driver function
if __name__ == "__main__":
   
    arr = [3, 10, 6, 7, 2, 5, 4]
    k = 4
    n = len(arr)
    print(findMinimumSwaps(arr, n, k))
 
# This code is contributed by Chitranayal


C#




// C# program to find Minimum number
// of swaps to get the position of
// the element if we provide an
// unsorted array to binary search.
 
using System;
public class GFG{
 
 
// Function to find minimum swaps.
    static int findMinimumSwaps(int[] arr, int n,
            int k) {
        int pos = 0, num_min, num_max,
                need_minimum, need_maximum, swaps;
        num_min = num_max = need_minimum = 0;
        need_maximum = swaps = 0;
 
        // Here we are getting number of
        // smaller and greater elements of k.
        for (int i = 0; i < n; i++) {
            if (arr[i] < k) {
                num_min++;
            } else if (arr[i] > k) {
                num_max++;
            }
        }
 
        // Here we are calculating the actual
        // position of k in the array.
        for (int i = 0; i < n; i++) {
            if (arr[i] == k) {
                pos = i;
                break;
            }
        }
 
        int left, right, mid;
        left = 0;
        right = n - 1;
 
        // Implementing binary search as
        // per the above-discussed cases.
        while (left <= right) {
            mid = (left + right) / 2;
 
            // If we find the k.
            if (arr[mid] == k) {
                break;
            } else if (arr[mid] > k) {
 
                // If we need minimum
                // element swap.
                if (pos > mid) {
                    need_minimum++;
                } else // Else the element is
                // at the right position.
                {
                    num_min--;
                }
 
                left = mid + 1;
            } else {
                if (pos < mid) // If we need maximum
                // element swap.
                {
                    need_maximum++;
                } else // Else element is at
                // the right position
                {
                    num_max--;
                }
 
                right = mid - 1;
            }
        }
 
        // Calculating the required swaps.
        if (need_minimum > need_maximum) {
            swaps = swaps + need_maximum;
            num_min = num_min - need_maximum;
            need_minimum = need_minimum - need_maximum;
            need_maximum = 0;
        } else {
            swaps = swaps + need_minimum;
            num_max = num_max - need_minimum;
            need_maximum = need_maximum - need_minimum;
            need_minimum = 0;
        }
 
        // If it is impossible.
        if (need_maximum > num_max || need_minimum > num_min) {
            return -1;
        } else {
            return (swaps + need_maximum + need_minimum);
        }
    }
 
// Driver function
    public static void Main() {
 
        int []arr = {3, 10, 6, 7, 2, 5, 4};
        int k = 4;
        int n = arr.Length;
        Console.WriteLine(findMinimumSwaps(arr, n, k));
    }
 
}
 
/*This code is contributed by PrinciRaj1992*/


Javascript




<script>
    // Javascript program to find Minimum number
    // of swaps to get the position of
    // the element if we provide an
    // unsorted array to binary search.
     
    // Function to find minimum swaps.
    function findMinimumSwaps(arr, n, k)
    {
        let pos, num_min, num_max,
        need_minimum, need_maximum, swaps;
        num_min = num_max = need_minimum = 0;
        need_maximum = swaps = 0;
 
        // Here we are getting number of
        // smaller and greater elements of k.
        for (let i = 0; i < n; i++) {
            if (arr[i] < k)
                num_min++;
 
            else if (arr[i] > k)
                num_max++;
        }
 
        // Here we are calculating the actual
        // position of k in the array.
        for (let i = 0; i < n; i++) {
            if (arr[i] == k) {
                pos = i;
                break;
            }
        }
 
        let left, right, mid;
        left = 0;
        right = n - 1;
 
        // Implementing binary search as
        // per the above-discussed cases.
        while (left <= right) {
            mid = parseInt((left + right) / 2, 10);
 
            // If we find the k.
            if (arr[mid] == k) {
                break;
            }
 
            else if (arr[mid] > k) {
 
                // If we need minimum
                // element swap.
                if (pos > mid)
                    need_minimum++;
 
                else
 
                    // Else the element is
                    // at the right position.
                    num_min--;
 
                left = mid + 1;
            }
 
            else {
                if (pos < mid)
 
                    // If we need maximum
                    // element swap.
                    need_maximum++;
 
                else
 
                    // Else element is at
                    // the right position
                    num_max--;
 
                right = mid - 1;
            }
        }
 
        // Calculating the required swaps.
        if (need_minimum > need_maximum) {
            swaps = swaps + need_maximum;
            num_min = num_min - need_maximum;
            need_minimum = need_minimum - need_maximum;
            need_maximum = 0;
        }
 
        else {
            swaps = swaps + need_minimum;
            num_max = num_max - need_minimum;
            need_maximum = need_maximum - need_minimum;
            need_minimum = 0;
        }
 
        // If it is impossible.
        if (need_maximum > num_max || need_minimum > num_min)
            return -1;
 
        else
            return (swaps + need_maximum + need_minimum);
    }
     
    let arr = [ 3, 10, 6, 7, 2, 5, 4 ], k = 4;
    let n = arr.length;
    document.write(findMinimumSwaps(arr, n, k));
     
    // This code is contributed by divyesh072019.
</script>


Output:  

2

Time Complexity: O(n)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads