Find Original Array From Doubled Array

Updated on 28 May, 2025
Find Original Array From Doubled Array header image

Problem Statement

The challenge involves working with two integer arrays, original and changed. Initially, original is manipulated by doubling each of its elements and appending these doubled values to itself. Following this, the augmented array is shuffled randomly to form changed. The task is to deduce the original array from the given changed array. If it is not possible to ascertain such an original array, where every element in original and its double exist in changed, the output should be an empty array. The order of elements in the resultant original array does not have to match any specific sequence.

Examples

Example 1

Input:

changed = [1,3,4,2,6,8]

Output:

[1,3,4]

Explanation:

One possible original array could be [1,3,4]:
- Twice the value of 1 is 1 * 2 = 2.
- Twice the value of 3 is 3 * 2 = 6.
- Twice the value of 4 is 4 * 2 = 8.
Other original arrays could be [4,3,1] or [3,1,4].

Example 2

Input:

changed = [6,3,0,1]

Output:

[]

Explanation:

changed is not a doubled array.

Example 3

Input:

changed = [1]

Output:

[]

Explanation:

changed is not a doubled array.

Constraints

  • 1 <= changed.length <= 105
  • 0 <= changed[i] <= 105

Approach and Intuition

  1. First, the input changed is checked for even number of elements. If not, it's immediately clear that it cannot be a valid "doubled" array.
  2. Sort the changed array. This step organizes the numbers such that any valid element and its double are aligned in an order.
  3. Use a hashmap to store the count of each number in changed.
  4. Iterate over the sorted changed:
    • For the current number, if its count in hashmap is already zero (already paired), continue to the next number.
    • Check if the double of the current element also exists in the hashmap.
    • Deduct the count from both the current number and its double in the hashmap.
    • If the count of the double of a number is insufficient, it indicates that changed cannot be a valid doubled array, thus, we return an empty array.
  5. Compile the deduced original from the steps, ensuring that every element and its double are accounted for adequately.
  6. If the process completes without hitches, we have our original. If any step fails, return an empty array as it implicates that forming original is infeasible with provided changed.

Example Explanation for Clarity

  • Consider the initial list changed = [1,3,4,2,6,8].
  • Sorting it gives [1, 2, 3, 4, 6, 8].
  • Using hashmap for counts: {1:1, 2:1, 3:1, 4:1, 6:1, 8:1}.
  • Deduce original by pairing 1 with 2, 3 with 6, and 4 with 8. The exhausted hashmap (all counts zero) confirms the successful retrieval of original.
  • On the flip side, for an array like changed = [6,3,0,1], immediately after recognizing an odd length, or failure in pairing across the hashmap checks, an empty array response is warranted, confirming the unsuitability of changed as a doubled array.

Solutions

  • C++
  • Java
cpp
class Solution {
public:
    vector<int> reconstructArray(vector<int>& modified) {
        if (modified.size() % 2 != 0) {
            return {};
        }

        int highestValue = 0;
        for (int n : modified) {
            highestValue = max(highestValue, n);
        }
        
        vector<int> counts(2 * highestValue + 1, 0);
        for (int value : modified) {
            counts[value]++;
        }

        vector<int> result;
        for (int value = 0; value <= highestValue; value++) {
            while (counts[value] > 0) {
                counts[value]--;
                
                int doubledValue = value * 2;
                if (counts[doubledValue] > 0) {
                    counts[doubledValue]--;
                    result.push_back(value);
                } else {
                    return {};
                }
            }
        }
        
        return result;
    }
};

This problem entails discovering the original array before each of its elements were possibly doubled and mixed to form a new array. The given C++ solution aims to achieve this by:

  • Checking if the input array length is even. If not, it immediately returns an empty array since a valid doubled array requires an even number of elements.
  • Determining the maximum value in the modified array to setup a frequency array.
  • Constructing a frequency array (named counts) to track how many times each number appears in the modified array.
  • Iterating through the possible values (from zero to the highest value found). For each number:
    • Decrements the count for the number if it's present.
    • Checks and decrements the count for double of this number. If the doubled number is present in the array, the original number is added to the result array.
    • If the doubled number is not present, it returns an empty array indicating there's no valid arrangement.

By ensuring that each original number and its double are present in the array, and reducing their counts accordingly, the algorithm reconstructs the original array. If any number or its double cannot be successfully paired and decremented, the operation aborts early with an empty array, signifying the impossibility of forming a valid original array.

java
class Solution {
    public int[] reconstructArray(int[] changed) {
        if (changed.length % 2 != 0) {
            return new int[0];
        }

        int highestValue = 0;
        for (int elem : changed) {
            highestValue = Math.max(highestValue, elem);
        }
        
        int[] frequency = new int[2 * highestValue + 1];
        for (int elem : changed) {
            frequency[elem]++;
        }
        
        int[] result = new int[changed.length / 2];
        int resIdx = 0;
        for (int num = 0; num <= highestValue; num++) {
            while (frequency[num] > 0) {
                frequency[num]--;
                
                int doubled = num * 2;
                if (frequency[doubled] > 0) {
                    frequency[doubled]--;
                    result[resIdx++] = num;
                } else {
                    return new int[0];
                }
            }
        }
        
        return result;
    }
};

This Java solution tackles the problem of reconstructing the original array from an array where each element from the original array is doubled. Here's how the approach works:

  1. Initially, check if the length of the input array changed is odd. If yes, immediately return an empty array as it's not possible to form an original array of integers if the changed array has an odd number of elements.
  2. Find the maximum value in the changed array. This helps to set up the array for counting frequencies, ensuring the size can accommodate all possible elements up to twice the maximum value.
  3. Set up a frequency array to count occurrences of each element in the changed array. This frequency array has a size large enough to account for the doubled values.
  4. Create an array result that will store the reconstructed original array. It has half the length of the changed array as each original element occurs twice in changed.
  5. Iterate over possible numbers from 0 to the highestValue, and for each number, reduce its count in the frequency array and check if its double also exists. If the double exists, reduce its frequency and add the number to the result array.
  6. If the double does not exist for any element, it indicates the changed array does not correctly represent doubled values from an original array, hence return an empty array.
  7. Finally, return the result array which contains the original array reconstructed from the changed array.

This solution efficiently decomposes the doubled array back to its original using frequency counts and careful checks for corresponding doubled values. The approach ensures the integrity of the original data structure and provides a clear reconstruction method or affirms the impossibility of such reconstruction.

Comments

No comments yet.