Shuffle the Array

Updated on 10 July, 2025
Shuffle the Array header image

Problem Statement

The task is to rearrange a given array 'nums', which consists of 2n elements. These elements are initially grouped in two parts; the first n elements (x1, x2, ..., xn) and the second n elements (y1, y2, ..., yn). Our goal is to interleave these two parts to form a new array where each element from the two groups alternates starting with the first element of the first group. Specifically, the new order should be [x1, y1, x2, y2, ..., xn, yn]. This rearrangement should be done while maintaining the relative order of elements within each group.

Examples

Example 1

Input:

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

Output:

[2,3,5,4,1,7]

Explanation:

Since x1=2, x2=5, x3=1, y1=3, y2=4, y3=7 then the answer is [2,3,5,4,1,7].

Example 2

Input:

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

Output:

[1,4,2,3,3,2,4,1]

Example 3

Input:

nums = [1,1,2,2], n = 2

Output:

[1,2,1,2]

Constraints

  • 1 <= n <= 500
  • nums.length == 2n
  • 1 <= nums[i] <= 10^3

Approach and Intuition

The problem is about interleaving two halves of an array. Here's a detailed step-by-step approach based on examples and constraints:

  1. Understand the division of the array: It's given that the array can be broken down into two halves - the first half with elements x, and the second half with elements y.

  2. Determine the length of each segment: Since the array itself is of length 2n, and it is equally split, both halves (x and y segments) will have n elements each.

  3. Process for interleaving:

    • Start from the first element of the x-segment and append it to the new array.
    • Immediately follow it by the first element from the y-segment.
    • Repeat this process sequentially i.e. x2 followed by y2, and so on, until all elements are interleaved.
  4. Use of an auxiliary array: While it might be tempting to rearrange the array in-place, using an auxiliary array to store the results initially is simpler and avoids complex index management.

From the examples-

  • For an input like nums = [2,5,1,3,4,7], n = 3, understanding it as two parts: x-part = [2,5,1] and y-part = [3,4,7] can help in visualizing the method to interleave them as [2,3,5,4,1,7].

This approach ensures that the relative order from each initial segment is preserved in the final output, adhering to the constraints provided. Input validations based on constraints ensure there are always exactly 2n elements and the value of n is within the specified range.

Solutions

  • C++
cpp
class Solution {
public:
    vector<int> shuffleArray(vector<int>& data, int length) {
        for (int idx = length; idx < 2 * length; ++idx) {
            int temp = data[idx] << 10;
            data[idx - length] |= temp;
        }
    
        int mask = (1 << 10) - 1;
    
        for (int idx = length - 1; idx >= 0; --idx) {
            int y = data[idx] >> 10;
            int x = data[idx] & mask;
            data[2 * idx + 1] = y;
            data[2 * idx] = x;
        }
        return data;
    }
};

This C++ solution implements a function to shuffle an array where the array is divided into two halves. The function shuffleArray accepts a reference to a vector of integers data and an integer length which represents the length of a half of the array.

  • Utilize bit manipulation to interleave the elements from the two halves of the array.
  • Store interleaved values in the first half temporarily with bitwise operations to save space.

Here's a breakdown of the operation:

  1. In the first for loop, iterate from idx = length to idx < 2 * length.
    • Shift each element in the second half 10 bits left and store it temporarily in the corresponding position in the first half, combining with the first half’s original data.
  2. Prepare a mask of low 10 bits to extract information in the later stage.
  3. In the second for loop, iterate from idx = length - 1 downto idx >= 0.
    • Extract the original 'y' element from the second half using a right shift by 10.
    • Extract the original 'x' element from the first half of the array using the mask.
    • Place these extracted values in the correct order (x, y) in the final array.

After the loops, the original vector data is transformed into a shuffled array consisting of alternating elements from the two halves. This approach maintains an in-place operation, ensuring efficiency by minimizing the extra space used, crucial for handling large data efficiently.

  • Java
java
class Solution {
    public int[] mixElements(int[] elements, int halfSize) {
        // Combine corresponding elements
        for (int idx = halfSize; idx < 2 * halfSize; ++idx) {
            int highPart = elements[idx] << 10;
            elements[idx - halfSize] |= highPart;
        }
    
        // Mask to isolate the lower ten bits
        int mask = (int) Math.pow(2, 10) - 1;
    
        // Arrange the shuffled elements in the array
        for (int i = halfSize - 1; i >= 0; --i) {
            int highPart = elements[i] >> 10;
            int lowPart = elements[i] & mask;
            elements[2 * i + 1] = highPart;
            elements[2 * i] = lowPart;
        }
        return elements;
    }
}

In the Java solution for shuffling an array, the provided code operates by first merging elements, then separating and ordering them in a specific shuffled pattern. Here's a breakdown of how the solution works:

  1. The method mixElements takes an array elements and an integer halfSize which should be half the length of the input array.
  2. The first loop runs from the halfway point of the array to the end. For each idx, it shifts the element 10 bits to the left (high part) and then combines it with the lower part of the original array using bitwise OR.
  3. A mask is established using Math.pow(2, 10) - 1 to isolate the lower ten bits, ensuring that during bit manipulation only the lowest 10 bits are affected.
  4. The second loop reassigns the values to shuffle the array. For each element, the high part is extracted and placed in the odd indices, while the low part goes to the even indices of the array.
  5. Finally, the method returns the shuffled elements array.

This approach utilizes bit level operations to store temporary values within the same integers, minimizing additional space usage beyond the given array. The operations are efficient and carefully executed to shuffle all elements appropriately.

  • JavaScript
js
var interleaveArrays = function(arr, count) {
    // Combining second half numbers into first half using bitwise operations
    for (let j = count; j < 2 * count; ++j) {
        let encodedSecond = arr[j] << 10;
        arr[j - count] |= encodedSecond;
    }
    
    // Bit mask to isolate the lower 10 bits
    let mask = (1 << 10) - 1;
    
    // Decoding the numbers from combined form to separate elements
    for (let j = count - 1; j >= 0; --j) {
        let extractedSecond = arr[j] >> 10;
        let extractedFirst = arr[j] & mask;
        arr[2 * j + 1] = extractedSecond;
        arr[2 * j] = extractedFirst;
    }
    return arr;
};

In the provided JavaScript solution, you'll learn how to shuffle an array using bitwise operations. Here’s how the function interleaveArrays works to combine and then separate array elements for shuffling:

  1. Interleaving Process: For every element in the second half of the input array arr (starting from index count to 2*count), the element is shifted left by 10 bits and combined with its corresponding element in the first half. This preserves both halves in each element of the first half of the array.

  2. Decoding Process: The encoded elements are decoded back to their original form using a predefined mask, (1 << 10) - 1, crafted to extract the lower 10 bits of any number. Each entry j from the modified first half is processed to separate the components:

    • The second (shifted earlier) element is retrieved by shifting right by 10 bits.
    • The corresponding first half element, encoded within the lower 10 bits, is retrieved by applying the mask.
    • These retrieved values are placed back into the array positions for the original elements.
  • Return: Finally, the transformed array is returned, where elements have been shuffled according to the process described, ensuring that data from both halves of the original array is mixed in a specific, reversible manner.

This approach is particularly useful for manipulating large datasets within a limited space, showcasing a clever use of bitwise operations for encoding and decoding efficiently within a single array structure.

  • Python
python
class Solution:
    def interleave(self, array: List[int], half: int) -> List[int]:
        # Encode each second half element with first half element
        for index in range(half, 2 * half):
            encoded = array[index] << 10
            array[index - half] |= encoded
    
        # Masks all bits below 10th position
        mask = (1 << 10) - 1
    
        # Reconstruct and separate the interleaved numbers
        for index in range(half - 1, -1, -1):
            # Retrieve second and first half numbers
            back_num = array[index] >> 10
            front_num = array[index] & mask
            array[2 * index + 1] = back_num
            array[2 * index] = front_num
        return array

The task is to shuffle an array effectively by interleaving its elements. In Python, this is achieved through a method named interleave in the Solution class. The method requires an array and a parameter, half, which specifies the middle index of the array.

  • The array is divided into two halves: the first half remains unchanged, while each element in the second half is encoded with the corresponding element from the first half.
  • Each integer from the second half is left shifted by 10 bits, thus encoding it. This encoded value is then combined with its corresponding element from the first half using a bitwise OR operation.
  • To decode and separate the interleaved numbers, apply a mask that isolates the lower 10 bits. This mask helps retrieve the original numbers from the first half of the array.
  • Iterate from halfway back to the start. For each element, the method extracts the original numbers using the mask and shifts the encoded number back ten bits to get the second half's original number.
  • Reconstructed numbers are placed back into the array in interleaving order.

Ensure half is correctly computed as half the length of the array before calling this method. The provided implementation adjusts values directly in the input array, resulting in a space-efficient in-place solution with linear time complexity.

Comments

No comments yet.