Minimum Operations to Sort Array with Custom Shuffling
Last Updated :
12 Jan, 2024
Given an array A[] of length N along with a string S, the task is to output the minimum number of operations required to sort A[]. If it’s not possible then output -1. You can apply the below operation on A[] using S as follows:
- Choose two distinct indices let’s say i and j such that (i != j) and S[i] != S[j]. Shuffle the elements of subarray A[i, j] as per your choice.
- Also, shuffle the corresponding characters of S according to those elements.
Examples:
Input: N = 3, A[] = {3, 2, 1}, S = ‘NSN’
Output: 2
Explanation: The operations are performed as:
- First operation:
- Choose i = 2 and j = 3 as S[2] = S and S[3] = N, where S[2] != S[3].
- Then subarray is A[2, 3] = {2, 1}.
- Now, shuffle A[2, 3] as {1, 2}. Updated A[] is {3, 1, 2}
- Values in S will also shuffle according to A[2, 3]. S[2, 3] was “SN”, then it will be “NS”. Updated S = “NNS”
- Second operation:
- Choose i = 1 and j = 3 as S[1] = N and S[3] = S.
- Then subarray is A[1, 3] = {3, 2, 1}.
- Now, shuffled A[1, 3] as {1, 2, 3}. Updated A[] is {1, 2, 3}
- Values in S will also shuffle according to A[1, 2, 3]. S[1, 3] was “NNS”, then it will be “NSN”. Updated S = “NSN”
- It can be verified that now A[] is sorted under 2 operations. It can be verified that these are the minimum number of operations. Thus, output is 2.
Input: N = 2, A[] = {2, 1}, S = SS
Output: -1
Explanation: It can be verified that it is not possible to sort A[] using given operation. Therefore, output is -1.
Approach: Implement the idea below to solve the problem
- First of all, we have to check if A[] is already sorted in increasing order or not, If already sorted then the minimum number of operations required is 0. For checking this, we made a function named as Is_sorted(A[]).
- Next, We will check, If all the characters in S are either ‘N’ or ‘S’. In such case, we can’t apply any operation because there wouldn’t be two indices such that S[i]!=S[j]. which would result in no change in the order of elements in the A[]. In such cases, it is not possible to sort the A[]. So, the output is -1.
- If the above two conditions fail, Then find the leftmost and rightmost ‘N’ and ‘S’ characters into the string S.
Checking for two possibilities:
If we can sort A[] by negating some elements between the first ‘N’ and last ‘S’ (inclusive) OR If we can sort A[] by swapping some elements between the first ‘S’ and last ‘N’ (inclusive). If either of these two possibilities is true, then we need only one operation to sort the array. Otherwise, we need 2 operations.
Finally, the minimum number of operations required to sort A[] is printed. It is always possible to sort A[] in at most 2 operations, If sorting is possible using given operation.
Note that the check() function in the program is used to determine if a subarray is already sorted or not by sorting it and comparing it with the original subarray.
Steps were taken to solve the problem:
- Initial Checks on A[]:
- Check, if A[] is already sorted or not. If it is, Output 0. Since no operations are needed.
- Also check if all characters in S are same (all ‘N’ or all ‘S’). If they are, then output -1. Since it’s impossible to sort A[] with the given operations.
- Find first and last occurrences of N and S:
- Then find the first and last occurrence of both ‘N’ and ‘S’ in the string in four variables let say firstN, lastN, firstS, and lastS.
- Check() Function:
- This function checks two subarrays: A[firstN, lastS] and A[firstS, lastN]. If either of these subarrays can be sorted to make the entire array sorted, it means it’s possible to sort the array with 1 operation.
- Output:
- Finally, if either subarray can be sorted to sort the entire array, Then output 1.
- Otherwise, output 2, indicating that at least two operations are needed to sort the array.
Code to implement the approach:
C++
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool check(vector< int > arr, int first, int last)
{
sort(arr.begin() + first, arr.begin() + last + 1);
if (is_sorted(arr.begin(), arr.end())) {
return true ;
}
return false ;
}
void min_operations( int N, vector< int > A, string S)
{
vector< int > A1(N);
A1 = A;
sort(A1.begin(), A1.end());
if (is_sorted(A.begin(), A.end())) {
cout << 0 << "\n";
return ;
}
int count = 0;
for ( int i = 0; i < N; i++) {
if (S[i] == 'N' ) {
count++;
}
}
if (count == N || count == 0) {
cout << "-1"
<< "\n";
return ;
}
int firstN = -1, firstS = -1, lastN = -1, lastS = -1;
for ( int i = 0; i < N; i++) {
if (S[i] == 'N' ) {
if (firstN == -1) {
firstN = i;
}
lastN = i;
}
else {
if (firstS == -1) {
firstS = i;
}
lastS = i;
}
}
int ans = 2;
if (check(A, firstN, lastS)
|| check(A, firstS, lastN)) {
ans = 1;
}
cout << ans << "\n";
}
int main()
{
int N = 2;
vector< int > A = { 2, 1 };
string S = "NN";
min_operations(N, A, S);
return 0;
}
|
Java
import java.util.*;
class GFG {
static boolean check(Vector<Integer> arr, int first,
int last)
{
Arrays.sort(arr.subList(first, last + 1 ).toArray());
return isSorted(arr);
}
static boolean isSorted(Vector<Integer> arr)
{
Vector<Integer> sortedArr = new Vector<>(arr);
sortedArr.sort( null );
return arr.equals(sortedArr);
}
static void minOperations( int N, Vector<Integer> A,
String S)
{
Vector<Integer> A1 = new Vector<>(A);
A1.sort( null );
if (isSorted(A)) {
System.out.println( 0 );
return ;
}
int count = 0 ;
for ( int i = 0 ; i < N; i++) {
if (S.charAt(i) == 'N' ) {
count++;
}
}
if (count == N || count == 0 ) {
System.out.println( "-1" );
return ;
}
int firstN = - 1 , firstS = - 1 , lastN = - 1 ,
lastS = - 1 ;
for ( int i = 0 ; i < N; i++) {
if (S.charAt(i) == 'N' ) {
if (firstN == - 1 ) {
firstN = i;
}
lastN = i;
}
else {
if (firstS == - 1 ) {
firstS = i;
}
lastS = i;
}
}
int ans = 2 ;
if (check(A, firstN, lastS)
|| check(A, firstS, lastN)) {
ans = 1 ;
}
System.out.println(ans);
}
public static void main(String[] args)
{
int N = 2 ;
Vector<Integer> A
= new Vector<>(Arrays.asList( 2 , 1 ));
String S = "NN" ;
minOperations(N, A, S);
}
}
|
Python3
def check(arr, first, last):
arr[first:last + 1 ] = sorted (arr[first:last + 1 ])
return arr = = sorted (arr)
def min_operations(N, A, S):
A1 = sorted (A)
if A = = A1:
print ( 0 )
return
count = S.count( 'N' )
if count = = N or count = = 0 :
print ( "-1" )
return
firstN = S.find( 'N' )
lastN = N - 1 - S[:: - 1 ].find( 'N' )
firstS = S.find( 'S' )
lastS = N - 1 - S[:: - 1 ].find( 'S' )
ans = 2
if check(A, firstN, lastS) or check(A, firstS, lastN):
ans = 1
print (ans)
if __name__ = = "__main__" :
N = 2
A = [ 2 , 1 ]
S = "NN"
min_operations(N, A, S)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
static bool Check(List< int > arr, int first, int last)
{
arr.Sort(first, last - first + 1, null );
return IsSorted(arr);
}
static bool IsSorted(List< int > arr)
{
List< int > sortedArr = new List< int >(arr);
sortedArr.Sort();
return arr.SequenceEqual(sortedArr);
}
static void MinOperations( int N, List< int > A, string S)
{
List< int > A1 = new List< int >(A);
A1.Sort();
if (IsSorted(A))
{
Console.WriteLine(0);
return ;
}
int count = S.Count(c => c == 'N' );
if (count == N || count == 0)
{
Console.WriteLine( "-1" );
return ;
}
int firstN = -1, firstS = -1, lastN = -1, lastS = -1;
for ( int i = 0; i < N; i++)
{
if (S[i] == 'N' )
{
if (firstN == -1)
firstN = i;
lastN = i;
}
else
{
if (firstS == -1)
firstS = i;
lastS = i;
}
}
int ans = 2;
if (Check(A, firstN, lastS) || Check(A, firstS, lastN))
ans = 1;
Console.WriteLine(ans);
}
public static void Main( string [] args)
{
int N = 2;
List< int > A = new List< int > { 2, 1 };
string S = "NN" ;
MinOperations(N, A, S);
}
}
|
Javascript
function check(arr, first, last) {
arr.splice(first, last - first + 1, ...arr.slice(first, last + 1).sort());
return JSON.stringify(arr) === JSON.stringify(arr.slice().sort());
}
function min_operations(N, A, S) {
const A1 = [...A].sort();
if (JSON.stringify(A) === JSON.stringify(A1)) {
console.log(0);
return ;
}
const count = (S.match(/N/g) || []).length;
if (count === N || count === 0) {
console.log( "-1" );
return ;
}
const firstN = S.indexOf('N ');
const lastN = N - 1 - [...S].reverse().indexOf(' N ');
const firstS = S.indexOf(' S ');
const lastS = N - 1 - [...S].reverse().indexOf(' S');
let ans = 2;
if (check(A, firstN, lastS) || check(A, firstS, lastN)) {
ans = 1;
}
console.log(ans);
}
const N = 2;
const A = [2, 1];
const S = "NN" ;
min_operations(N, A, S);
|
Time Complexity: O(N)
Auxiliary space: O(N), As extra Vector A1 is used.
Share your thoughts in the comments
Please Login to comment...