Sort array by performing swapping under certain condition
Last Updated :
26 Feb, 2024
Given an array of positive elements arr[] of size N. You can select any index i such that i + 1 < N and swap arr[i], arr[i + 1] if they have the same number of set bits in their binary representation. The task is to determine whether it is possible to sort the array in ascending order by swapping any number of times. If it is possible, you should return true, otherwise return false.
Examples:
Input: N = 5, arr = {8,4,2,30,15}
Output: true
Explanation: Sequence of Operations:
- Swap nums[0] with nums[1]. Valid because 8 and 4 have one set bit each. Array becomes {4,8,2,30,15}.
- Swap nums[1] with nums[2]. Valid because 8 and 2 have one set bit each. Array becomes {4,2,8,30,15.
- Swap nums[0] with nums[1]. Valid because 4 and 2 have one set bit each. Array becomes {2,4,8,30,15}.
- Swap nums[3] with nums[4]. Valid because 30 and 15 have four set bits each. Array becomes {2,4,8,15,30}.
Input: arr = {3,16,8,4,2}
Output: false
Explanation: No sequence of operations can sort the array in ascending order.
Approach: To solve the problem, follow the below idea:
The problem can be solved by partitioning the input array into contiguous subarrays such that each subarrays has numbers with the same number of set bits. Now, in each of these subarrays, we can apply swap operation between this subarray to get the elements in sorted form. We'll keep doing this for all such possible subarray and finally we'll check if the array becomes sorted or not.
Step-by-step algorithm:
- Initialize variables pi for storing the starting of subarray whose set bit count remains the same in this subarray.
- Loop through the array, count set bits, and sort current subarray segments when the set bit count changes.
- Create a copy of the array, sort it, and compare with the original array.
Below is the implementation of the approach:
C++
#include<bits/stdc++.h>
using namespace std;
bool canSortArray(vector<int>& arr) {
int n = arr.size();
// Initialize previous count of set bits
int prev = __builtin_popcount(arr[0]);
// Initialize previous index
int pi = 0, i;
for(i = 1; i < n; i++){
// Count set bits of current number
int count = __builtin_popcount(arr[i]);
// If count of set bits changes, sort the previous segment
if(count != prev){
sort(arr.begin() + pi, arr.begin() + i);
prev = count;
pi = i;
}
}
// Sort the last segment
sort(arr.begin() + pi, arr.begin() + i);
// Create a copy of the array and sort it
vector<int> nums = arr;
sort(arr.begin(), arr.end());
// Check if the sorted array is equal to the original array
return (arr == nums);
}
int main() {
// Define the input array
vector<int> arr = {8, 4, 2, 30, 15};
// Call the function and print the result
cout << "The array can be sorted: " << (canSortArray(arr) ? "true" : "false") << endl;
return 0;
}
Java
import java.util.Arrays;
import java.util.Vector;
public class ArraySortability {
static boolean canSortArray(Vector<Integer> arr) {
int n = arr.size();
// Initialize previous count of set bits
int prev = Integer.bitCount(arr.get(0));
// Initialize previous index
int pi = 0, i;
for (i = 1; i < n; i++) {
// Count set bits of current number
int count = Integer.bitCount(arr.get(i));
// If count of set bits changes, sort the previous segment
if (count != prev) {
arr.subList(pi, i).sort(null);
prev = count;
pi = i;
}
}
// Sort the last segment
arr.subList(pi, i).sort(null);
// Create a copy of the array and sort it
Vector<Integer> nums = new Vector<>(arr);
arr.sort(null);
// Check if the sorted array is equal to the original array
return arr.equals(nums);
}
public static void main(String[] args) {
// Define the input array
Vector<Integer> arr = new Vector<>(Arrays.asList(8, 4, 2, 30, 15));
// Call the function and print the result
System.out.println("The array can be sorted: " + (canSortArray(arr) ? "true" : "false"));
}
}
Python3
def can_sort_array(arr):
n = len(arr)
# Initialize previous count of set bits
prev = bin(arr[0]).count('1')
# Initialize previous index
pi = 0
i = 1
while i < n:
# Count set bits of the current number
count = bin(arr[i]).count('1')
# If count of set bits changes, sort the previous segment
if count != prev:
arr[pi:i] = sorted(arr[pi:i])
prev = count
pi = i
i += 1
# Sort the last segment
arr[pi:i] = sorted(arr[pi:i])
# Create a copy of the array and sort it
nums = arr.copy()
arr.sort()
# Check if the sorted array is equal to the original array
return arr == nums
# Define the input array
arr = [8, 4, 2, 30, 15]
# Call the function and print the result
print("The array can be sorted:", "true" if can_sort_array(arr) else "false")
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG {
static bool CanSortArray(int[] arr)
{
int n = arr.Length;
// Initialize previous count of set bits
int prev = CountSetBits(arr[0]);
// Initialize previous index
int pi = 0, i = 0;
for (i = 1; i < n; i++) {
// Count set bits of current number
int count = CountSetBits(arr[i]);
// If count of set bits changes, sort the
// previous segment
if (count != prev) {
Array.Sort(arr, pi, i - pi);
prev = count;
pi = i;
}
}
// Sort the last segment
Array.Sort(arr, pi, i - pi);
// Create a copy of the array and sort it
int[] nums = arr;
Array.Sort(arr, 0, n - 1);
// Check if the sorted array is equal to the
// original array
return (arr == nums);
}
// To count set bits
static int CountSetBits(int n)
{
int count = 0;
while (n > 0) {
count += n & 1;
n >>= 1;
}
return count;
}
public static void Main(string[] args)
{
// Define the input array
int[] arr = { 8, 4, 2, 30, 15 };
// Call the function and print the result
Console.WriteLine(
"The array can be sorted: "
+ (CanSortArray(arr) ? "true" : "false"));
}
}
// This code is contributed by Susobhan Akhuli
JavaScript
// JavaScript program for the above approach
// Function to count the number of set bits
function popcount(num) {
let count = 0;
while (num) {
num &= num - 1;
count++;
}
return count;
}
// Function to swap 2 elements of array
function swap(arr, xp, yp)
{
var temp = arr[xp];
arr[xp] = arr[yp];
arr[yp] = temp;
}
// Function to sort the array slice in range
function sortSLice(arr, l, r){
var i, j;
for (i = l; i < r + 1 + 1; i++)
{
for (j = l; j < r - i + 1; j++)
{
if (arr[j] > arr[j + 1])
{
swap(arr, j, j + 1);
}
}
}
}
// Function to check if the array can be sorted by sorting segments based on the count of set bits
function canSortArray(arr) {
let n = arr.length;
// Initialize previous count of set bits
let prev = popcount(arr[0]);
// Initialize previous index
let pi = 0;
for(let i = 1; i < n; i++){
// Count set bits of current number
let count = popcount(arr[i]);
// If count of set bits changes, sort the previous segment
if(count !== prev){
// Sort array in range
sortSLice(arr, pi, i);
prev = count;
pi = i;
}
}
// Sort the last segment
sortSLice(arr, pi, n);
// Create a copy of the array and sort it
let nums = arr.slice();
arr.sort((a, b) => a - b);
// Check if the sorted array is equal to the original array
return JSON.stringify(arr) === JSON.stringify(nums);
}
// Define the input array
let arr = [8, 4, 2, 30, 15];
// Call the function and print the result
console.log("The array can be sorted: " + (canSortArray(arr) ? "true" : "false"));
// This code is contributed by Susobhan Akhuli
OutputThe array can be sorted: true
Time Complexity: O(N * log (N)), where N is the size of the input array arr[].
Auxiliary Space: O(N)
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem