Find if Array Can Be Sorted

Updated on 30 May, 2025
Find if Array Can Be Sorted header image

Problem Statement

The task is based on manipulating a given array of positive integers named nums, which is structured in a 0-indexed format. The core operation allowed in this scenario is swapping any two adjacent elements of the array, but the condition for such a swap is that both elements must contain the same number of 1's in their binary representation. This operation can be repeated numerous times, including not performing any swaps at all.

The primary objective is to determine if it is possible to sort the array in ascending order using the above-defined operation. The result should be returned as true if the array can be sorted in that manner, or false otherwise.

Examples

Example 1

Input:

nums = [8,4,2,30,15]

Output:

true

Explanation:

Let's look at the binary representation of every element. The numbers 2, 4, and 8 have one set bit each with binary representation "10", "100", and "1000" respectively. The numbers 15 and 30 have four set bits each with binary representation "1111" and "11110".
We can sort the array using 4 operations:
- Swap nums[0] with nums[1]. This operation is valid because 8 and 4 have one set bit each. The array becomes [4,8,2,30,15].
- Swap nums[1] with nums[2]. This operation is valid because 8 and 2 have one set bit each. The array becomes [4,2,8,30,15].
- Swap nums[0] with nums[1]. This operation is valid because 4 and 2 have one set bit each. The array becomes [2,4,8,30,15].
- Swap nums[3] with nums[4]. This operation is valid because 30 and 15 have four set bits each. The array becomes [2,4,8,15,30].
The array has become sorted, hence we return true.
Note that there may be other sequences of operations which also sort the array.

Example 2

Input:

nums = [1,2,3,4,5]

Output:

true

Explanation:

The array is already sorted, hence we return true.

Example 3

Input:

nums = [3,16,8,4,2]

Output:

false

Explanation:

It can be shown that it is not possible to sort the input array using any number of operations.

Constraints

  • 1 <= nums.length <= 100
  • 1 <= nums[i] <= 28

Approach and Intuition

The primary intuition here revolves around understanding the binary representation of numbers—particularly, the count of set bits (1's).

  • Each example elucidates different scenarios:
    • Example 1:

      • Input: nums = [8,4,2,30,15]
      • The numbers (2, 4, 8) have one set bit each, allowing swaps among them. Similarly, the numbers (30, 15) with four set bits each can be rearranged amongst themselves. The allowable manipulations enable sorting of the entire array, returning true.
    • Example 2:

      • Input: nums = [1,2,3,4,5]
      • This example forms a naturally sorted array from the outset, thus avoiding the need for any operations, returning true.
    • Example 3:

      • Input: nums = [3,16,8,4,2]
      • Despite different possibilities of swaps for numbers with the same set bits, it's impossible to fully sort the entire sequence in ascending order due to the mixed distribution of set bits that isolate some numbers (like 3 with two set bits). Here, swapping alone based on set bits constraint cannot yield a sorted array, so it returns false.

From observing the given examples, the strategy broadly hints at checking if:

  1. Grouping numbers by their set bit counts can be sorted independently.
  2. Post group sorting, if these grouped numbers themselves form an ascending sequence based on their minimum and maximum values, ensuring a globally sorted structure.

Understanding the constraints where the length of the array (nums.length) can go up to 100 and each element's value (nums[i]) ranges from 1 to 28 also implies that efficient manipulation and checks can be managed within these bounds.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    bool isSortable(vector<int>& elements) {
        int size = elements.size();
        vector<int> copiedElements = elements;

        for (int i = 0; i < size - 1; i++) {
            if (copiedElements[i] <= copiedElements[i + 1]) {
                continue;
            } else {
                if (__builtin_popcount(copiedElements[i]) == __builtin_popcount(copiedElements[i + 1])) {
                    swap(copiedElements[i], copiedElements[i + 1]);
                } else {
                    return false;
                }
            }
        }

        for (int i = size - 1; i >= 1; i--) {
            if (copiedElements[i] >= copiedElements[i - 1]) {
                continue;
            } else {
                if (__builtin_popcount(copiedElements[i]) == __builtin_popcount(copiedElements[i - 1])) {
                    swap(copiedElements[i], copiedElements[i - 1]);
                } else {
                    return false;
                }
            }
        }

        return true;
    }
};

The provided C++ solution defines a method that checks if an array can be sorted with a specific condition: elements can be swapped if they have the same number of 1s in their binary representation. This is checked using the __builtin_popcount function which returns the count of 1s in the binary form of the number.

The function executes a step-wise validation:

  1. Initialize size and create a copy of the input array.
  2. Iterate through the array from the beginning to the second-last element:
    • If the current element is less than or equal to the next, continue.
    • If not, check if the two elements have the same number of 1s using __builtin_popcount. If true, swap them; if false, return false indicating the array cannot be sorted this way.
  3. Repeat similar iteration but from end to start:
    • If the current element is greater than or equal to the previous one, continue.
    • If not, again check for the same number of 1s and swap if true. Return false otherwise.

Finally, the function returns true if both checks pass, indicating that the array can be sorted using this specific swapping rule. This solution ensures efficient use of conditional swaps based on binary representation properties.

java
class Solution {

    public boolean canRearrange(int[] arr) {
        int len = arr.length;

        // Create a copy of the array
        int[] copiedArray = Arrays.copyOf(arr, len);

        // Ascending pass: Move larger or equal items right
        for (int i = 0; i < len - 1; i++) {
            if (copiedArray[i] > copiedArray[i + 1]) {
                // Compare bit representations
                if (Integer.bitCount(copiedArray[i]) == Integer.bitCount(copiedArray[i + 1])) {
                    int swap = copiedArray[i];
                    copiedArray[i] = copiedArray[i + 1];
                    copiedArray[i + 1] = swap; // Perform swap operation
                } else {
                    return false; // Immediate exit if conditions not met
                }
            }
        }

        // Descending pass: Move smaller or equal items left
        for (int i = len - 1; i > 0; i--) {
            if (copiedArray[i] < copiedArray[i - 1]) {
                // Compare bit representations again
                if (Integer.bitCount(copiedArray[i]) == Integer.bitCount(copiedArray[i - 1])) {
                    int swap = copiedArray[i];
                    copiedArray[i] = copiedArray[i - 1];
                    copiedArray[i - 1] = swap; // Perform swap operation
                } else {
                    return false; // Immediate exit if conditions not met
                }
            }
        }

        return true; // Successful sorting and reordering check
    }
}

In this solution summary, review the Java implementation of checking whether an array can be sorted based on specific criteria involving bit representation of integers. The method canRearrange attempts to determine whether an input array can be reordered into ascending order, but with additional checks on binary representation of elements before swapping.

  • The process starts by creating a copy of the input array to work without altering the original data.
  • An initial loop works through the array, comparing adjacent elements. If an element is larger than the next, the number of 1s in their binary forms are compared. If equal, these elements are swapped.
  • Should adjacency conditions fail, meaning if the element has a differing count of 1s in its binary representation compared to the next element, the function immediately returns false.
  • The array undergoes a reverse iteration in the "descending pass," following similar conditions as in the first loop, but this time focusing on ensuring smaller or equal items can be correctly moved left.
  • If all conditions during these traversals are satisfied, and the entire array can thus be rearranged according to the specified rules without violation, the function yields a true value indicating a successful sort and rearrangement is possible.

In essence, this solution checks the rearrangement possibility not just based on the numerical value but also entailing a specific binary characteristic of array elements.

python
class Solution:
    def canSort(self, arr):
        length = len(arr)
        temp_arr = arr.copy()  # Duplicate the input list

        # First Pass: Go forward through the list
        # Push the largest values to the right
        for i in range(length - 1):
            if temp_arr[i] > temp_arr[i + 1]:
                # Swap if set bits are the same
                if bin(temp_arr[i]).count("1") == bin(temp_arr[i + 1]).count("1"):
                    temp_arr[i], temp_arr[i + 1] = temp_arr[i + 1], temp_arr[i]
                else:
                    return False  # Can't swap, sorting not possible

        # Second Pass: Go backward through the list
        # Pull smallest values to the left
        for i in range(length - 1, 0, -1):
            if temp_arr[i] < temp_arr[i - 1]:
                # Swap if set bits match
                if bin(temp_arr[i]).count("1") == bin(temp_arr[i - 1]).count("1"):
                    temp_arr[i], temp_arr[i - 1] = temp_arr[i - 1], temp_arr[i]
                else:
                    return False  # Can't swap, sorting not possible

        return True  # Successful sorting possible after two passes

The provided Python 3 code defines a method, canSort, which determines whether an input array can be sorted based on a specific condition. The canSort function checks if an array can be sorted into non-decreasing order by allowing swaps between consecutive elements only if both elements have the same number of set bits in their binary representation.

Here's a step-by-step breakdown of what the function does:

  1. Create a copy of the input array to avoid modifying the original.
  2. Perform a forward pass through the copied array:
    • Compare each pair of consecutive elements.
    • Swap them if the number of set bits (1s in the binary representation) are the same.
    • If they differ, conclude that sorting is not possible and return False.
  3. Perform a backward pass through the array:
    • This time ensuring that any larger elements found earlier which were not correctly positioned can now be considered for swapping.
    • Apply the same set bit swap criteria.
    • If a mismatch occurs, return False.
  4. If the function does not return False during any of its passes, it means that it's possible to sort the array under the given conditions, thus it returns True.

This implementation is specifically designed around the condition which allows swaps of consecutive elements only when their binary representations have an equal number of 1 bits. It effectively ensures that sorting tasks respect this unique constraint.

Comments

No comments yet.