给定大小为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中。
- 使用Binary Search,找到给定数组中存在的值的索引,该值小于或等于值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
0 4
时间复杂度: O(Q * N * log N)
辅助空间: O(N)