Check if the array can be sorted using swaps between given indices only
Last Updated :
25 Nov, 2023
Given an array arr[] of size N consisting of distinct integers from range [0, N - 1] arranged in a random order. Also given a few pairs where each pair denotes the indices where the elements of the array can be swapped. There is no limit on the number of swaps allowed. The task is to find if it is possible to arrange the array in ascending order using these swaps. If possible then print Yes else print No.
Examples:
Input: arr[] = {0, 4, 3, 2, 1, 5}, pairs[][] = {{1, 4}, {2, 3}}
Output: Yes
swap(arr[1], arr[4]) -> arr[] = {0, 1, 3, 2, 4, 5}
swap(arr[2], arr[3]) -> arr[] = {0, 1, 2, 3, 4, 5}
Input: arr[] = {1, 2, 3, 0, 4}, pairs[][] = {{2, 3}}
Output: No
Approach: The given problem can be considered as a graph problem where N denotes the total number of nodes in the graph and each swapping pair denotes an undirected edge in the graph. We have to find out if it is possible to convert the input array in the form of {0, 1, 2, 3, ..., N - 1}.
Let us call the above array as B. Now find out all the connected components of both the arrays and if the elements differ for at least one component then the answer is No else the answer is Yes.
Below is the implementation of the above approach:
CPP
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
// Function that returns true if the array elements
// can be sorted with the given operation
bool canBeSorted(int N, vector<int> a, int P,
vector<pair<int, int> > vp)
{
// To create the adjacency list of the graph
vector<int> v[N];
// Boolean array to mark the visited nodes
bool vis[N] = { false };
// Creating adjacency list for undirected graph
for (int i = 0; i < P; i++) {
v[vp[i].first].push_back(vp[i].second);
v[vp[i].second].push_back(vp[i].first);
}
for (int i = 0; i < N; i++) {
// If not already visited
// then apply BFS
if (!vis[i]) {
queue<int> q;
vector<int> v1;
vector<int> v2;
// Set visited to true
vis[i] = true;
// Push the node to the queue
q.push(i);
// While queue is not empty
while (!q.empty()) {
int u = q.front();
v1.push_back(u);
v2.push_back(a[u]);
q.pop();
// Check all the adjacent nodes
for (auto s : v[u]) {
// If not visited
if (!vis[s]) {
// Set visited to true
vis[s] = true;
q.push(s);
}
}
}
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
// If the connected component does not
// contain same elements then return false
if (v1 != v2)
return false;
}
}
return true;
}
// Driver code
int main()
{
vector<int> a = { 0, 4, 3, 2, 1, 5 };
int n = a.size();
vector<pair<int, int> > vp = { { 1, 4 }, { 2, 3 } };
int p = vp.size();
if (canBeSorted(n, a, p, vp))
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java implementation of the approach
import java.io.*;
import java.util.*;
class GFG
{
// Function that returns true if the array elements
// can be sorted with the given operation
static boolean canBeSorted(int N, ArrayList<Integer> a,
int p, ArrayList<ArrayList<Integer>> vp)
{
// To create the adjacency list of the graph
ArrayList<ArrayList<Integer>> v = new ArrayList<ArrayList<Integer>>();
for(int i = 0; i < N; i++)
{
v.add(new ArrayList<Integer>());
}
// Boolean array to mark the visited nodes
boolean[] vis = new boolean[N];
// Creating adjacency list for undirected graph
for (int i = 0; i < p; i++)
{
v.get(vp.get(i).get(0)).add(vp.get(i).get(1));
v.get(vp.get(i).get(1)).add(vp.get(i).get(0));
}
for (int i = 0; i < N; i++)
{
// If not already visited
// then apply BFS
if (!vis[i])
{
Queue<Integer> q = new LinkedList<>();
ArrayList<Integer> v1 = new ArrayList<Integer>();
ArrayList<Integer> v2 = new ArrayList<Integer>();
// Set visited to true
vis[i] = true;
// Push the node to the queue
q.add(i);
// While queue is not empty
while (q.size() > 0)
{
int u = q.poll();
v1.add(u);
v2.add(a.get(u));
// Check all the adjacent nodes
for(int s: v.get(u))
{
// If not visited
if (!vis[s])
{
// Set visited to true
vis[s] = true;
q.add(s);
}
}
}
Collections.sort(v1);
Collections.sort(v2);
// If the connected component does not
// contain same elements then return false
if(!v1.equals(v2))
{
return false;
}
}
}
return true;
}
// Driver code
public static void main (String[] args)
{
ArrayList<Integer> a = new ArrayList<Integer>(Arrays.asList(0, 4, 3, 2, 1, 5));
int n = a.size();
ArrayList<ArrayList<Integer>> vp = new ArrayList<ArrayList<Integer>>();
vp.add(new ArrayList<Integer>(Arrays.asList(1, 4)));
vp.add(new ArrayList<Integer>(Arrays.asList(2, 3)));
int p = vp.size();
if (canBeSorted(n, a, p, vp))
{
System.out.println("Yes");
}
else
{
System.out.println("No");
}
}
}
// This code is contributed by avanitrachhadiya2155
Python3
# Python3 implementation of the approach
from collections import deque as queue
# Function that returns true if the array elements
# can be sorted with the given operation
def canBeSorted(N, a, P, vp):
# To create the adjacency list of the graph
v = [[] for i in range(N)]
# Boolean array to mark the visited nodes
vis = [False]*N
# Creating adjacency list for undirected graph
for i in range(P):
v[vp[i][0]].append(vp[i][1])
v[vp[i][1]].append(vp[i][0])
for i in range(N):
# If not already visited
# then apply BFS
if (not vis[i]):
q = queue()
v1 = []
v2 = []
# Set visited to true
vis[i] = True
# Push the node to the queue
q.append(i)
# While queue is not empty
while (len(q) > 0):
u = q.popleft()
v1.append(u)
v2.append(a[u])
# Check all the adjacent nodes
for s in v[u]:
# If not visited
if (not vis[s]):
# Set visited to true
vis[s] = True
q.append(s)
v1 = sorted(v1)
v2 = sorted(v2)
# If the connected component does not
# contain same elements then return false
if (v1 != v2):
return False
return True
# Driver code
if __name__ == '__main__':
a = [0, 4, 3, 2, 1, 5]
n = len(a)
vp = [ [ 1, 4 ], [ 2, 3 ] ]
p = len(vp)
if (canBeSorted(n, a, p, vp)):
print("Yes")
else:
print("No")
# This code is contributed by mohit kumar 29
C#
// Include namespace system
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
public class GFG
{
// Function that returns true if the array elements
// can be sorted with the given operation
public static bool canBeSorted(int N, List<int> a, int p, List<List<int>> vp)
{
// To create the adjacency list of the graph
var v = new List<List<int>>();
for (int i = 0; i < N; i++)
{
v.Add(new List<int>());
}
// Boolean array to mark the visited nodes
bool[] vis = new bool[N];
// Creating adjacency list for undirected graph
for (int i = 0; i < p; i++)
{
v[vp[i][0]].Add(vp[i][1]);
v[vp[i][1]].Add(vp[i][0]);
}
for (int i = 0; i < N; i++)
{
// If not already visited
// then apply BFS
if (!vis[i])
{
var q = new LinkedList<int>();
var v1 = new List<int>();
var v2 = new List<int>();
// Set visited to true
vis[i] = true;
// Push the node to the queue
q.AddLast(i);
// While queue is not empty
while (q.Count > 0)
{
var u = q.First();
q.RemoveFirst();
v1.Add(u);
v2.Add(a[u]);
// Check all the adjacent nodes
foreach (int s in v[u])
{
// If not visited
if (!vis[s])
{
// Set visited to true
vis[s] = true;
q.AddLast(s);
}
}
}
v1.Sort();
v2.Sort();
// If the connected component does not
// contain same elements then return false
if (!v1.SequenceEqual(v2))
{
return false;
}
}
}
return true;
}
// Driver code
public static void Main(String[] args)
{
var<int> a = new List<int>(new[] {0,4,3,2,1,5});
var n = a.Count;
List<List<int>> vp = new List<List<int>>();
vp.Add(new List<int>(new[] {1,4}));
vp.Add(new List<int>(new[] {2,3}));
var p = vp.Count;
if (GFG.canBeSorted(n, a, p, vp))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
}
// This code is contributed by utkarshshirode02
JavaScript
<script>
// Javascript implementation of the approach
// Function that returns true if the array elements
// can be sorted with the given operation
function canBeSorted(N,a,p,vp)
{
// To create the adjacency list of the graph
let v= [];
for(let i = 0; i < N; i++)
{
v.push([]);
}
// Boolean array to mark the visited nodes
let vis = new Array(N);
// Creating adjacency list for undirected graph
for (let i = 0; i < p; i++)
{
v[vp[i][0]].push(vp[i][1]);
v[vp[i][1]].push(vp[i][0]);
}
for (let i = 0; i < N; i++)
{
// If not already visited
// then apply BFS
if (!vis[i])
{
let q = [];
let v1 = [];
let v2 = [];
// Set visited to true
vis[i] = true;
// Push the node to the queue
q.push(i);
// While queue is not empty
while (q.length > 0)
{
let u = q.shift();
v1.push(u);
v2.push(a[u]);
// Check all the adjacent nodes
for(let s=0;s<v[u].length;s++)
{
// If not visited
if (!vis[v[u][s]])
{
// Set visited to true
vis[v[u][s]] = true;
q.push(v[u][s]);
}
}
}
v1.sort(function(c,d){return c-d;});
v2.sort(function(c,d){return c-d;});
// If the connected component does not
// contain same elements then return false
if(v1.toString()!=(v2).toString())
{
return false;
}
}
}
return true;
}
// Driver code
let a = [0, 4, 3, 2, 1, 5];
let n = a.length;
let vp = [];
vp.push([1, 4]);
vp.push([2, 3]);
let p = vp.length;
if (canBeSorted(n, a, p, vp))
{
document.write("Yes");
}
else
{
document.write("No");
}
// This code is contributed by unknown2108
</script>
Time Complexity: O(N)
Auxiliary Space: O(N)
Another Method (Union-Find algorithm)
Approach
The given problem can be solve using the concept of Union-Find algorithm. We can consider each element of the array as a node in a graph, and the pairs as edges between the nodes. If two nodes are connected through a pair, it means that we can swap their values. The way is to check if we can form a connected graph of nodes, so that each node represents a number in the array, and each edge represents a pair that can be swapped. If we can form such a graph, it means that we can swap the elements to obtain a sorted array.
Algorithm
- Initialize a parent array of size N, where parent[i] represents the parent of the ith node in the graph. Initially, parent[i] = i for all i.
- Iterate through each pair, and for each pair (u, v), perform the following steps:
- a. Find the parent of u and v using the find() function.
- b. If the parents are not equal, set the parent of v to u using the union() function.
- Iterate through the array arr[], and for each element arr[i], check if its parent is equal to i. If there exists any element i such that parent[i] is not equal to i, it means that we cannot form a connected graph, and hence it is not possible to sort the array using the given pairs. Print "No" and return.
- If all elements have the same parent, it means that we can form a connected graph, and hence it is possible to sort the array using the given pairs. Print "Yes" and return.
C++
#include <iostream>
#include <vector>
using namespace std;
// Find operation of Union-Find algorithm
int find(int parent[], int i) {
if (parent[i] == i) // If i is the parent of itself, return i
return i;
parent[i] = find(parent, parent[i]); // Path compression
return parent[i];
}
// Union operation of Union-Find algorithm
void union_sets(int parent[], int i, int j) {
parent[find(parent, j)] = find(parent, i); // Connect the two sets by setting the parent of one to the other
}
// Function to check if it's possible to sort the array using the given pairs
string can_sort_array(vector<int> arr, vector<pair<int, int>> pairs) {
int n = arr.size();
// Initialize the parent array with each node being a separate set
int parent[n];
for (int i = 0; i < n; i++)
parent[i] = i;
// Merge the sets based on the given pairs
for (auto p : pairs)
union_sets(parent, p.first, p.second);
// Check if each element is connected to its correct index
for (int i = 0; i < n; i++) {
if (find(parent, i) != find(parent, arr[i])) // If the parent of i is not the same as the parent of arr[i]
return "No"; // Return "No" as the array cannot be sorted using the given pairs
}
return "Yes"; // If all elements are connected to their correct index, return "Yes"
}
int main() {
vector<int> arr = {0, 4, 3, 2, 1, 5};
vector<pair<int, int>> pairs = {{1, 4}, {2, 3}};
cout << can_sort_array(arr, pairs) << endl; // Output: Yes
arr = {1, 2, 3, 0, 4};
pairs = {{2, 3}};
cout << can_sort_array(arr, pairs) << endl; // Output: No
return 0;
}
Java
//Java code for this approach
import java.util.*;
class Main {
// Find operation of Union-Find algorithm
static int find(int[] parent, int i) {
if (parent[i] == i) // If i is the parent of itself, return i
return i;
parent[i] = find(parent, parent[i]); // Path compression
return parent[i];
}
// Union operation of Union-Find algorithm
static void unionSets(int[] parent, int i, int j) {
parent[find(parent, j)] = find(parent, i); // Connect the two sets by setting the parent of one to the other
}
// Function to check if it's possible to sort the array using the given pairs
static String canSortArray(List<Integer> arr, List<Pair<Integer, Integer>> pairs) {
int n = arr.size();
// Initialize the parent array with each node being a separate set
int[] parent = new int[n];
for (int i = 0; i < n; i++)
parent[i] = i;
// Merge the sets based on the given pairs
for (Pair<Integer, Integer> p : pairs)
unionSets(parent, p.first, p.second);
// Check if each element is connected to its correct index
for (int i = 0; i < n; i++) {
if (find(parent, i) != find(parent, arr.get(i))) // If the parent of i is not the same as the parent of arr[i]
return "No"; // Return "No" as the array cannot be sorted using the given pairs
}
return "Yes"; // If all elements are connected to their correct index, return "Yes"
}
// Driver code
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(0, 4, 3, 2, 1, 5);
List<Pair<Integer, Integer>> pairs = Arrays.asList(new Pair<>(1, 4), new Pair<>(2, 3));
System.out.println(canSortArray(arr, pairs)); // Output: Yes
arr = Arrays.asList(1, 2, 3, 0, 4);
pairs = Arrays.asList(new Pair<>(2, 3));
System.out.println(canSortArray(arr, pairs)); // Output: No
}
}
class Pair<A, B> {
public A first;
public B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
}
// Sundaram Singh
Python
def find(parent, i):
if parent[i] == i:
return i
parent[i] = find(parent, parent[i]) # Path compression
return parent[i]
def union_sets(parent, i, j):
parent[find(parent, j)] = find(parent, i)
def can_sort_array(arr, pairs):
n = len(arr)
parent = [i for i in range(n)] # Initialize the parent array with each node being a separate set
# Merge the sets based on the given pairs
for p in pairs:
union_sets(parent, p[0], p[1])
# Check if each element is connected to its correct index
for i in range(n):
if find(parent, i) != find(parent, arr[i]):
return "No"
return "Yes"
arr = [0, 4, 3, 2, 1, 5]
pairs = [(1, 4), (2, 3)]
print(can_sort_array(arr, pairs)) # Output: Yes
arr = [1, 2, 3, 0, 4]
pairs = [(2, 3)]
print(can_sort_array(arr, pairs)) # Output: No
C#
using System;
using System.Collections.Generic;
class Program
{
// Find operation of Union-Find algorithm
static int Find(int[] parent, int i)
{
if (parent[i] == i) // If i is the parent of itself, return i
return i;
parent[i] = Find(parent, parent[i]); // Path compression
return parent[i];
}
// Union operation of Union-Find algorithm
static void UnionSets(int[] parent, int i, int j)
{
parent[Find(parent, j)] = Find(parent, i); // Connect the two sets by setting the
// parent of one to the other
}
// Function to check if it's possible to sort the array using the given pairs
static string CanSortArray(List<int> arr, List<Tuple<int, int>> pairs)
{
int n = arr.Count;
// Initialize the parent array with each node being a separate set
int[] parent = new int[n];
for (int i = 0; i < n; i++)
parent[i] = i;
// Merge the sets based on the given pairs
foreach (var p in pairs)
UnionSets(parent, p.Item1, p.Item2);
// Check if each element is connected to its correct index
for (int i = 0; i < n; i++)
{
if (Find(parent, i) != Find(parent, arr[i])) // If the parent of i is not the
// same as the parent of arr[i]
return "No"; // Return "No" as the array cannot be sorted using the given pairs
}
return "Yes"; // If all elements are connected to their correct index, return "Yes"
}
static void Main()
{
List<int> arr = new List<int> { 0, 4, 3, 2, 1, 5 };
List<Tuple<int, int>> pairs = new List<Tuple<int,
int>> { Tuple.Create(1, 4), Tuple.Create(2, 3) };
Console.WriteLine(CanSortArray(arr, pairs)); // Output: Yes
arr = new List<int> { 1, 2, 3, 0, 4 };
pairs = new List<Tuple<int, int>> { Tuple.Create(2, 3) };
Console.WriteLine(CanSortArray(arr, pairs)); // Output: No
}
}
JavaScript
// Find operation of Union-Find algorithm
function find(parent, i) {
if (parent[i] === i) { // If i is the parent of itself, return i
return i;
}
parent[i] = find(parent, parent[i]); // Path compression
return parent[i];
}
// Union operation of Union-Find algorithm
function unionSets(parent, i, j) {
parent[find(parent, j)] = find(parent, i); // Connect the two sets by setting the parent of one to the other
}
// Function to check if it's possible to sort the array using the given pairs
function canSortArray(arr, pairs) {
const n = arr.length;
// Initialize the parent array with each node being a separate set
const parent = Array.from({ length: n }, (_, i) => i);
// Merge the sets based on the given pairs
for (const [first, second] of pairs) {
unionSets(parent, first, second);
}
// Check if each element is connected to its correct index
for (let i = 0; i < n; i++) {
if (find(parent, i) !== find(parent, arr[i])) { // If the parent of i is not the same as the parent of arr[i]
return "No"; // Return "No" as the array cannot be sorted using the given pairs
}
}
return "Yes"; // If all elements are connected to their correct index, return "Yes"
}
// Main function
function main() {
const arr1 = [0, 4, 3, 2, 1, 5];
const pairs1 = [[1, 4], [2, 3]];
console.log(canSortArray(arr1, pairs1)); // Output: Yes
const arr2 = [1, 2, 3, 0, 4];
const pairs2 = [[2, 3]];
console.log(canSortArray(arr2, pairs2)); // Output: No
}
// Call the main function
main();
Time complexity: O((m + n) log n).
Auxiliary Space: O(n), as it uses an array of length n to keep track of the parent of each node in the Union-Find data structure.
Similar Reads
Check if the array can be sorted only if the elements on given positions can be swapped
Given an array arr[] of length N and another array P[] containing {a1, a2, ... ak} which represents the positions of the given array arr[], the task is to check if the array can be sorted by only swapping the elements' arr[ai], arr[ai+1] where 'i' is some element in the array P[].Examples: Input: ar
8 min read
Check if array can be sorted with one swap
Given an array containing N elements. Find if it is possible to sort it in non-decreasing order using atmost one swap. Examples: Input : arr[] = {1, 2, 3, 4} Output : YES The array is already sorted Input : arr[] = {3, 2, 1} Output : YES Swap 3 and 1 to get [1, 2, 3] Input : arr[] = {4, 1, 2, 3} Out
11 min read
Check if Array can be sorted in non-decreasing order using given operations
Given an array arr[] of size N consisting of positive integers, the task is to check if the array can be sorted in non-decreasing order by performing the following operations: Select two adjacent elements.Swap the elements and invert their signs.All elements in the sorted array received at the end,
8 min read
Check if a decreasing Array can be sorted using Triple cyclic shift
Given an arr[] of size N whose elements are sorted in descending order. The task is to find if the given array can be sorted in ascending order by performing a minimum number of triple cyclic right swaps. Print the indexes involved in each of the triple cyclic right swap. Triple Cyclic Right Swap re
8 min read
Check if array can be sorted by swapping adjacent elements of opposite parity
Given an array A of size n, the task is to check if the array can be sorted in increasing order, if the only operation allowed is swapping the adjacent elements if they are of opposite parity. The operation can be done any number of times. Examples: Input : n = 4, A = [1, 6, 51, 16]Output: YESExplan
9 min read
Check if Array can be sorted by swapping adjacent elements having odd sum
Given an array arr[], the task is to check if the array can be sorted using the given operation any number of times. In one operation, you can swap any two adjacent elements if their sum is odd. Examples: Input: arr[] = [1, 6, 31, 14]Output: YesExplanation: Swap 31 and 14 (31 + 14 = 45 which is odd)
7 min read
Check if array can be sorted by swapping pairs having GCD equal to the smallest element in the array
Given an array arr[] of size N, the task is to check if an array can be sorted by swapping only the elements whose GCD (greatest common divisor) is equal to the smallest element of the array. Print âYesâ if it is possible to sort the array. Otherwise, print âNoâ. Examples: Input: arr[] = {4, 3, 6, 6
11 min read
Check whether a given array is a k sorted array or not
Given an array of n distinct elements. Check whether the given array is a k sorted array or not. A k sorted array is an array where each element is at most k distances away from its target position in the sorted array. For example, let us consider k is 2, an element at index 7 in the sorted array, c
12 min read
Check if an array of pairs can be sorted by swapping pairs with different first elements
Given an array arr[] consisting of N pairs, where each pair represents the value and ID respectively, the task is to check if it is possible to sort the array by the first element by swapping only pairs having different IDs. If it is possible to sort, then print "Yes". Otherwise, print "No". Example
11 min read
Check if an Array can be Sorted by picking only the corner Array elements
Given an array arr[] consisting of N elements, the task is to check if the given array can be sorted by picking only corner elements i.e., elements either from left or right side of the array can be chosen. Examples: Input: arr[] = {2, 3, 4, 10, 4, 3, 1} Output: Yes Explanation: The order of picking
5 min read