给定长度为n和整数k的未排序数组,请在使用二进制搜索之前找到最小交换以获取k的位置。在这里,我们可以任意交换任意两个数字。如果我们无法通过交换元素获得位置,请打印“ -1”。
例子:
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.
方法:在讨论该方法之前,我们必须假定此处不交换对。我们只需要计算交换的最小数量,这样如果我们将新创建的数组提供给二进制搜索,则可以得到k的位置。为此,我们需要将给定的数组传递给二进制搜索,并专注于以下方面:
- 在进行二值搜索之前,我们需要计算最小元素的数量,即k的num_min和最大元素的数量,即k的num_max 。在这里,num_min表示k的较小可用元素的数量,num_max表示可用于交换的较大的可用元素的数量
- k在给定数组中的实际位置。
现在,以下是在执行二进制搜索过程中将发生的测试用例:-
情况1:如果arr [mid]大于k,但k的位置大于mid。二进制搜索会将我们带到(arr [0]到arr [mid-1])。但是实际上我们的元素介于两者之间(arr [mid + 1]到arr [last元素])。因此,为了朝正确的方向前进,我们需要小于k的东西,以便可以将其与arr [mid]交换,并且可以在arr [mid + 1]到arr [last_element]之间移动。因此,这里我们需要进行一次交换,即need_minimum 。
情况2:如果arr [mid]小于k,但k的位置小于mid。二进制搜索会将我们带到(arr [mid + 1]到arr [last_element])。但实际上,我们的元素介于两者之间(arr [0]至arr [mid-1])。因此,为了朝正确的方向前进,我们需要大于k的值,以便可以将其与arr [mid]交换,并且可以在arr [0]到arr [mid-1]之间移动。因此,这里我们需要进行一次交换,即need_maximum 。
情况3:
如果arr [mid]大于k并且k的位置小于mid。现在,在这种情况下,二进制搜索将可以正常工作。但是,等等,这是我们必须处理的重要事情。众所周知,在这种情况下,二进制搜索可以正常工作,arr [mid]处于正确的位置,因此不会在任何交换中使用它,因此在这里,我们必须减少其较大的可用元素之一,即从num_max。当arr [mid]小于k且k的位置大于mid的情况也是如此。在这里,我们必须减少其较小的可用元素之一,即从num_min开始。
情况4:如果arr [mid] == k或pos == mid,那么我们可以轻松地从二元搜索中得出。
因此,到目前为止,我们已经计算了need_minimum(即交换所需的最小元素数), need_maximum(即交换所需的最大元素数), num_max(即k中仍可用于交换的较大元素的总数)和num_min(即总数)可用于交换的k中的最小元素数。
现在在这里我们必须考虑两种情况:
情况1:如果need_minimum大于need_maximum。在这种情况下,我们必须将所有这些所需的最大元素交换为较小的k。因此,我们必须使用num_min中的较小元素。现在,所有need_maximum交换均已完成。这里最主要的是,当我们将所有这些所需的最大元素交换为较小的元素时,这些较小的元素将获得正确的位置。因此,我们间接完成了一些所需的较小元素交换,这些交换将计算为need_minimum – need_maximum ,可用的num_min也将是num_min – need_maximum 。现在,我们必须计算剩余的need_minimum交换。如果我们有足够的num_min,即num_min> need_minimum,我们可以计算这些掉期。对于这种情况,交换将为need_maximum + need_minimum,否则为-1。当我们的need_minimum小于need_maximum时,同样的概念也适用。
以下是上述方法的基本实现:
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
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
输出:
2