Queries to find minimum swaps required to sort given array with updates
Last Updated :
04 May, 2021
Given a sorted array arr[] of size N and an array Q[][] having queries in the form of {x, y}. In each query {x, y}, update the given array by incrementing the value arr[x] by y. The task is to find the minimum number of swaps required to sort the array obtained after performing each query in the given array individually.
Examples:
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.
Naive Approach: The simplest approach is to update the given array by incrementing the value arr[x] by y for each query {x, y}. After that, traverse the updated array and swap arr[x] to the right while arr[x] is greater than arr[x+1], incrementing x each time then swap arr[x] to the left while arr[x] is smaller than arr[x-1], decrementing x each time. Print the absolute difference between the initial and the final value of x.
Time Complexity: O(Q*N2) where N is the length of the given array and Q is the total number of queries.
Auxiliary Space: O(N)
Efficient Approach: The idea is to use Binary Search to find the minimum number of swaps required to make the given array sorted after each query. Follow the below steps to solve the problem:
- For each query {x, y}, store the value arr[x]+y in a variable newElement.
- Using Binary Search, find the index of the value present in the given array that is just smaller than or equal to the value newElement.
- If no such value can be found, print x, otherwise let that value be at index j.
- Print the absolute difference between the index i and the index j.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int computePos( int arr[], int n,
int value)
{
if (value < arr[0])
return 0;
if (value > arr[n - 1])
return n - 1;
int start = 0;
int end = n - 1;
while (start < end) {
int mid = (start + end + 1) / 2;
if (arr[mid] >= value)
end = mid - 1;
else
start = mid;
}
return start;
}
void countShift( int arr[], int n,
vector<vector< int > >& queries)
{
for ( auto q : queries) {
int index = q[0];
int update = q[1];
int newElement = arr[index]
+ update;
int newIndex = computePos(
arr, n, newElement);
cout << abs (newIndex - index)
<< " " ;
}
}
int main()
{
int arr[] = { 2, 3, 4, 5, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
vector<vector< int > > queries
= { { 0, -1 }, { 4, -11 } };
countShift(arr, N, queries);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int computePos( int arr[],
int n, int value)
{
if (value < arr[ 0 ])
return 0 ;
if (value > arr[n - 1 ])
return n - 1 ;
int start = 0 ;
int end = n - 1 ;
while (start < end)
{
int mid = (start +
end + 1 ) / 2 ;
if (arr[mid] >= value)
end = mid - 1 ;
else
start = mid;
}
return start;
}
static void countShift( int arr[], int n,
Vector<Vector<Integer> > queries)
{
for (Vector<Integer> q : queries)
{
int index = q.get( 0 );
int update = q.get( 1 );
int newElement = arr[index] + update;
int newIndex = computePos(arr, n,
newElement);
System.out.print(Math.abs(newIndex -
index) + " " );
}
}
public static void main(String[] args)
{
int arr[] = { 2 , 3 , 4 , 5 , 6 };
int N = arr.length;
Vector<Vector<Integer> > queries =
new Vector<>();
Vector<Integer> v =
new Vector<>();
Vector<Integer> v1 =
new Vector<>();
v.add( 0 );
v.add(- 1 );
queries.add(v);
v1.add( 4 );
v1.add(- 11 );
queries.add(v1);
countShift(arr, N, queries);
}
}
|
Python3
def computePos(arr, n, value):
if (value < arr[ 0 ]):
return 0
if (value > arr[n - 1 ]):
return n - 1
start = 0
end = n - 1
while (start < end):
mid = (start + end + 1 ) / / 2
if (arr[mid] > = value):
end = mid - 1
else :
start = mid
return start
def countShift(arr, n, queries):
for q in queries:
index = q[ 0 ]
update = q[ 1 ]
newElement = arr[index] + update
newIndex = computePos(arr, n, newElement)
print ( abs (newIndex - index), end = " " )
if __name__ = = '__main__' :
arr = [ 2 , 3 , 4 , 5 , 6 ]
N = len (arr)
queries = [ [ 0 , - 1 ], [ 4 , - 11 ] ]
countShift(arr, N, queries)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int computePos( int []arr,
int n, int value)
{
if (value < arr[0])
return 0;
if (value > arr[n - 1])
return n - 1;
int start = 0;
int end = n - 1;
while (start < end)
{
int mid = (start +
end + 1) / 2;
if (arr[mid] >= value)
end = mid - 1;
else
start = mid;
}
return start;
}
static void countShift( int []arr, int n,
List<List< int > >
queries)
{
foreach (List< int > q in queries)
{
int index = q[0];
int update = q[1];
int newElement = arr[index] +
update;
int newIndex = computePos(arr, n,
newElement);
Console.Write(Math.Abs(newIndex -
index) + " " );
}
}
public static void Main(String[] args)
{
int []arr = {2, 3, 4, 5, 6};
int N = arr.Length;
List<List< int > > queries =
new List<List< int >>();
List< int > v =
new List< int >();
List< int > v1 =
new List< int >();
v.Add(0);
v.Add(-1);
queries.Add(v);
v1.Add(4);
v1.Add(-11);
queries.Add(v1);
countShift(arr, N, queries);
}
}
|
Javascript
<script>
function computePos(arr, n, value)
{
if (value < arr[0])
return 0;
if (value > arr[n - 1])
return n - 1;
var start = 0;
var end = n - 1;
while (start < end) {
var mid = parseInt((start + end + 1) / 2);
if (arr[mid] >= value)
end = mid - 1;
else
start = mid;
}
return start;
}
function countShift(arr, n, queries)
{
for ( var i =0; i< queries.length; i++)
{
var index = queries[i][0];
var update = queries[i][1];
var newElement = arr[index]
+ update;
var newIndex = computePos(
arr, n, newElement);
document.write( Math.abs(newIndex - index)
+ " " );
}
}
var arr = [ 2, 3, 4, 5, 6 ];
var N = arr.length;
var queries = [[ 0, -1 ], [ 4, -11 ]];
countShift(arr, N, queries);
</script>
|
Time Complexity: O(Q*N*log N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...