Open In App

Sort array by performing swapping under certain condition

Last Updated : 26 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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


Output

The 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)



    Like Article
    Suggest improvement
    Share your thoughts in the comments

    Similar Reads