给定大小为N的排序数组arr[]和具有{x, y}形式的查询的数组Q[][] 。在每个查询{x, y} 中,通过将值arr[x]增加y 来更新给定数组。任务是找到对在给定数组中单独执行每个查询后获得的数组进行排序所需的最小交换次数。
例子:
Input: arr[] = {2, 3, 4, 5, 6}, Q[][] = {{2, 8}, {3, 1}}
Output: 2 0
Explanation:
Following are the number of swaps required for each query:
Query 1: Increment arr[2] by 8. Therefore, arr[] = {2, 3, 12, 5, 6}.
To make this array sorted, shift 12 right by 2 positions.
Now arr[] = {2, 3, 5, 6, 12}. Hence, it requires 2 swaps.
Query 2: Increment arr[3] by 1. Therefore, arr[] = {2, 3, 4, 6, 6}.
The array is still sorted. Hence, it requires 0 swaps.
Input: arr[] = {2, 3, 4, 5, 6}, Q[][] = {{0, -1}, {4, -11}};
Output: 0 4
Explanation:
Following are the number of swaps required for each query:
Query 1: Increment arr[0] by -1. Therefore, arr[] = {1, 3, 4, 5, 6}.
The array is still sorted. Hence, it requires 0 swaps.
Query 2: Increment arr[4] by -11. Therefore, arr[] = {2, 3, 4, 5, -5}.
To make this array sorted, shift -5 left by 4 positions.
Now arr[] = {-5, 2, 3, 4, 5}. Hence, it requires 4 swaps.
朴素的方法:最简单的方法是通过为每个查询{x, y}将值arr[x]增加y来更新给定的数组。之后,遍历更新后的数组并向右交换arr[x] ,而arr[x]大于arr[x+1] ,每次递增x然后向左交换arr[x]而arr[x]为小于arr[x-1] ,每次递减x 。打印x的初始值和最终值之间的绝对差值。
时间复杂度: O(Q*N 2 ),其中 N 是给定数组的长度,Q 是查询的总数。
辅助空间: O(N)
有效的方法:这个想法是使用二分搜索来找到使给定数组在每次查询后排序所需的最小交换次数。请按照以下步骤解决问题:
- 对于每个查询{x, y} ,将值arr[x]+y 存储在变量newElement 中。
- 使用二分搜索,找到给定数组中存在的值的索引,该值刚好小于或等于值newElement 。
- 如果找不到这样的值,则打印x ,否则让该值位于索引j 处。
- 打印索引i和索引j之间的绝对差异。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to return the position of
// the given value using binary search
int computePos(int arr[], int n,
int value)
{
// Return 0 if every value is
// greater than the given value
if (value < arr[0])
return 0;
// Return N-1 if every value is
// smaller than the given value
if (value > arr[n - 1])
return n - 1;
// Perform Binary Search
int start = 0;
int end = n - 1;
// Iterate till start < end
while (start < end) {
// Find the mid
int mid = (start + end + 1) / 2;
// Update start and end
if (arr[mid] >= value)
end = mid - 1;
else
start = mid;
}
// Return the position of
// the given value
return start;
}
// Function to return the number of
// make the array sorted
void countShift(int arr[], int n,
vector >& queries)
{
for (auto q : queries) {
// Index x to update
int index = q[0];
// Increment value by y
int update = q[1];
// Set newElement equals
// to x + y
int newElement = arr[index]
+ update;
// Compute the new index
int newIndex = computePos(
arr, n, newElement);
// Print the minimum number
// of swaps
cout << abs(newIndex - index)
<< " ";
}
}
// Driver Code
int main()
{
// Given array arr[]
int arr[] = { 2, 3, 4, 5, 6 };
int N = sizeof(arr) / sizeof(arr[0]);
// Given Queries
vector > queries
= { { 0, -1 }, { 4, -11 } };
// Function Call
countShift(arr, N, queries);
return 0;
}
Java
// Java program for the
// above approach
import java.util.*;
class GFG{
// Function to return the position of
// the given value using binary search
static int computePos(int arr[],
int n, int value)
{
// Return 0 if every value is
// greater than the given value
if (value < arr[0])
return 0;
// Return N-1 if every value is
// smaller than the given value
if (value > arr[n - 1])
return n - 1;
// Perform Binary Search
int start = 0;
int end = n - 1;
// Iterate till start < end
while (start < end)
{
// Find the mid
int mid = (start +
end + 1) / 2;
// Update start and end
if (arr[mid] >= value)
end = mid - 1;
else
start = mid;
}
// Return the position of
// the given value
return start;
}
// Function to return the number of
// make the array sorted
static void countShift(int arr[], int n,
Vector > queries)
{
for (Vector q : queries)
{
// Index x to update
int index = q.get(0);
// Increment value by y
int update = q.get(1);
// Set newElement equals
// to x + y
int newElement = arr[index] + update;
// Compute the new index
int newIndex = computePos(arr, n,
newElement);
// Print the minimum number
// of swaps
System.out.print(Math.abs(newIndex -
index) + " ");
}
}
// Driver Code
public static void main(String[] args)
{
// Given array arr[]
int arr[] = {2, 3, 4, 5, 6};
int N = arr.length;
// Given Queries
Vector > queries =
new Vector<>();
Vector v =
new Vector<>();
Vector v1 =
new Vector<>();
v.add(0);
v.add(-1);
queries.add(v);
v1.add(4);
v1.add(-11);
queries.add(v1);
// Function Call
countShift(arr, N, queries);
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program for the above approach
# Function to return the position of
# the given value using binary search
def computePos(arr, n, value):
# Return 0 if every value is
# greater than the given value
if (value < arr[0]):
return 0
# Return N-1 if every value is
# smaller than the given value
if (value > arr[n - 1]):
return n - 1
# Perform Binary Search
start = 0
end = n - 1
# Iterate till start < end
while (start < end):
# Find the mid
mid = (start + end + 1) // 2
# Update start and end
if (arr[mid] >= value):
end = mid - 1
else:
start = mid
# Return the position of
# the given value
return start
# Function to return the number of
# make the array sorted
def countShift(arr, n, queries):
for q in queries:
# Index x to update
index = q[0]
# Increment value by y
update = q[1]
# Set newElement equals
# to x + y
newElement = arr[index] + update
# Compute the new index
newIndex = computePos(arr, n, newElement)
# Print the minimum number
# of swaps
print(abs(newIndex - index), end = " ")
# Driver Code
if __name__ == '__main__':
# Given array arr[]
arr = [ 2, 3, 4, 5, 6 ]
N = len(arr)
# Given Queries
queries = [ [ 0, -1 ], [4, -11 ] ]
# Function Call
countShift(arr, N, queries)
# This code is contributed by mohit kumar 29
C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to return the position of
// the given value using binary search
static int computePos(int []arr,
int n, int value)
{
// Return 0 if every value is
// greater than the given value
if (value < arr[0])
return 0;
// Return N-1 if every value is
// smaller than the given value
if (value > arr[n - 1])
return n - 1;
// Perform Binary Search
int start = 0;
int end = n - 1;
// Iterate till start
// < end
while (start < end)
{
// Find the mid
int mid = (start +
end + 1) / 2;
// Update start and end
if (arr[mid] >= value)
end = mid - 1;
else
start = mid;
}
// Return the position of
// the given value
return start;
}
// Function to return the number of
// make the array sorted
static void countShift(int []arr, int n,
List >
queries)
{
foreach (List q in queries)
{
// Index x to update
int index = q[0];
// Increment value by y
int update = q[1];
// Set newElement equals
// to x + y
int newElement = arr[index] +
update;
// Compute the new index
int newIndex = computePos(arr, n,
newElement);
// Print the minimum number
// of swaps
Console.Write(Math.Abs(newIndex -
index) + " ");
}
}
// Driver Code
public static void Main(String[] args)
{
// Given array []arr
int []arr = {2, 3, 4, 5, 6};
int N = arr.Length;
// Given Queries
List > queries =
new List>();
List v =
new List();
List v1 =
new List();
v.Add(0);
v.Add(-1);
queries.Add(v);
v1.Add(4);
v1.Add(-11);
queries.Add(v1);
// Function Call
countShift(arr, N, queries);
}
}
// This code is contributed by 29AjayKumar
Javascript
0 4
时间复杂度: O(Q*N*log N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live