CLOSE
🛠️ Settings

Problem Statement

Given an integer array changed, which contains 2n elements, where each element in some original array original and its double appear in the changed array, return the original array. If the changed array cannot be a valid doubled array, return an empty array.

Examples

Example 1:

Input: changed = [1, 3, 4, 2, 6, 8]
Output: [1, 3, 4]

Explanation: The elements [2, 6, 8] are doubled of the element [1, 3, 4]
Example 2:

Input: changed = [6, 3, 0, 1]
Output: []

Explanation: 6 is double of 3 however, 0 and 1 and not related anyhow, so return empty array.

Different Approaches

1️⃣ Hashing

Approach:

  1. Sort the array: The first step is to sort the changed array. This allows us to process smaller numbers before their doubles, making it easier to match pairs.
  2. Use a frequency map: Use a frequency map (hash map) to count occurrences of each element in the changed array. For each element x, try to find its double 2 * x in the map.
  3. Process each element:
    • For each element x in the sorted changed array:
      • If x is already used (i.e., its frequency is 0), skip it.
      • Check if there is a 2 * x available in the frequency map. If not, the array is invalid.
      • Decrement the count of x and 2 * x in the map, and add x to the original array.
  4. Edge case: If there are odd numbers of zeros in the array, it’s invalid since you can't form pairs.

Dry Run:

Initialization:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  3  |  4  |  2  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
Sort the array:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
Store the frequencies of each element in a map:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
             
map =   key  value
      +-----+-----+
      |  1  |  1  |
      +-----+-----+
      |  2  |  1  |
      +-----+-----+
      |  3  |  1  |
      +-----+-----+
      |  4  |  1  |
      +-----+-----+
      |  6  |  1  |
      +-----+-----+
      |  8  |  1  |
      +-----+-----+
Process each element
First Iteration:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
             ^
             |
             i
             
map =   key  value
      +-----+-----+
      |  1  |  1  |
      +-----+-----+
      |  2  |  1  |
      +-----+-----+
      |  3  |  1  |
      +-----+-----+
      |  4  |  1  |
      +-----+-----+
      |  6  |  1  |
      +-----+-----+
      |  8  |  1  |
      +-----+-----+

         +-----+
result = |     |
         +-----+

Check if changed[i]'s count is zero in map, meaning it is already processed (it is double of someone's).
  False
Check if the double of changed[i]'s exist in map or not.
  1*2 = 2, Yes it do exists.
Push changed[i] in the result vector, decrement the frequency count
of changed[i] and its double from the map.
Second Iteration:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
                   ^
                   |
                   i
             
map =   key  value
      +-----+-----+
      |  1  |  0  |
      +-----+-----+
      |  2  |  0  |
      +-----+-----+
      |  3  |  1  |
      +-----+-----+
      |  4  |  1  |
      +-----+-----+
      |  6  |  1  |
      +-----+-----+
      |  8  |  1  |
      +-----+-----+

         +-----+
result = |  1  |
         +-----+

Check if changed[i]'s count is zero in map, meaning it is already processed (it is double of someone's).
  True, Continue to the next iteration.
Third Iteration:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
                         ^
                         |
                         i
             
map =   key  value
      +-----+-----+
      |  1  |  0  |
      +-----+-----+
      |  2  |  0  |
      +-----+-----+
      |  3  |  1  |
      +-----+-----+
      |  4  |  1  |
      +-----+-----+
      |  6  |  1  |
      +-----+-----+
      |  8  |  1  |
      +-----+-----+

         +-----+
result = |  1  |
         +-----+

Check if changed[i]'s count is zero in map, meaning it is already processed (it is double of someone's).
  False
Check if the double of changed[i]'s exist in map or not.
  3*2 = 6, Yes it do exists.
Push changed[i] in the result vector, decrement the frequency count
of changed[i] and its double from the map.
Fourth Iteration:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
                               ^
                               |
                               i
             
map =   key  value
      +-----+-----+
      |  1  |  0  |
      +-----+-----+
      |  2  |  0  |
      +-----+-----+
      |  3  |  0  |
      +-----+-----+
      |  4  |  1  |
      +-----+-----+
      |  6  |  0  |
      +-----+-----+
      |  8  |  1  |
      +-----+-----+

         +-----+-----+
result = |  1  |  3  |
         +-----+-----+

Check if changed[i]'s count is zero in map, meaning it is already processed (it is double of someone's).
  False
Check if the double of changed[i]'s exist in map or not.
  4*2 = 8, Yes it do exists.
Push i in the result vector, decrement the frequency count
of i and its double from the map.
Fifth Iteration:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
                                     ^
                                     |
                                     i
             
map =   key  value
      +-----+-----+
      |  1  |  0  |
      +-----+-----+
      |  2  |  0  |
      +-----+-----+
      |  3  |  0  |
      +-----+-----+
      |  4  |  0  |
      +-----+-----+
      |  6  |  0  |
      +-----+-----+
      |  8  |  0  |
      +-----+-----+

         +-----+-----+-----+
result = |  1  |  3  |  4  |
         +-----+-----+-----+

Check if i's count is zero in map, meaning it is already processed (it is
double of someone's).
  True, Continue to the next iteration.
Sixth Iteration:
          +-----+-----+-----+-----+-----+-----+
changed = |  1  |  2  |  3  |  4  |  6  |  8  |
          +-----+-----+-----+-----+-----+-----+
             0     1     2     3     4     5
                                           ^
                                           |
                                           i
             
map =   key  value
      +-----+-----+
      |  1  |  0  |
      +-----+-----+
      |  2  |  0  |
      +-----+-----+
      |  3  |  0  |
      +-----+-----+
      |  4  |  0  |
      +-----+-----+
      |  6  |  0  |
      +-----+-----+
      |  8  |  0  |
      +-----+-----+

         +-----+-----+-----+
result = |  1  |  3  |  4  |
         +-----+-----+-----+

Check if i's count is zero in map, meaning it is already processed (it is
double of someone's).
  True, Continue to the next iteration.

Code:

Using for each loop:
vector<int> findOriginalArray(vector<int>& changed) {
    if (changed.size() % 2 != 0) {
        // If the length of the changed array is odd, return an empty array
        return {};
    }
    
    // Step 1: Sort the array
    sort(changed.begin(), changed.end());
    
    // Step 2: Create a frequency map
    unordered_map<int, int> freq;
    for (int num : changed) {
        freq[num]++;
    }
    
    vector<int> original;
    
    // Step 3: Process each element in the sorted changed array
    for (int num : changed) {  // Corrected: Iterate over elements, not indices
        if (freq[num] == 0) {
            // If num is already used, skip it
            continue;
        }
        if (freq[num * 2] == 0) {
            // If the double of num does not exist, return empty array
            return {};
        }
        // Add num to the original array
        original.push_back(num);
        
        // Decrement the frequency of num and its double
        freq[num]--;
        freq[num * 2]--;
    }
    
    return original;
}
Using Simple for loop:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;

vector<int> findOriginalArray(vector<int>& changed) {
    if (changed.size() % 2 != 0) {
        // If the length of the changed array is odd, return an empty array
        return {};
    }
    
    // Step 1: Sort the array
    sort(changed.begin(), changed.end());
    
    // Step 2: Create a frequency map
    unordered_map<int, int> freq;
    for (int num : changed) {
        freq[num]++;
    }
    
    vector<int> original;
    
    // Step 3: Process each element
    for (int num = 0; num < changed.size(); num++) {
        if (freq[changed[num]] == 0) {
            // If num is already used, skip it
            continue;
        }
        if (freq[changed[num] * 2] == 0) {
            // If the double of num does not exist, return empty array
            return {};
        }
        // Add num to the original array
        original.push_back(changed[num]);
        
        // Decrement the frequency of num and its double
        freq[changed[num]]--;
        freq[changed[num] * 2]--;
    }
    
    return original;
}

int main() {
    vector<int> changed = {0, 0, 0, 0};
    
    vector<int> original = findOriginalArray(changed);
    
    // Output the original array
    if (!original.empty()) {
        for (int num : original) {
            cout << num << " ";
        }
    } else {
        cout << "[]";  // If no valid original array, output empty array
    }
    
    return 0;
}

Complexity Analysis:

  • Time Complexity:
    • Sorting the array: O(n log n).
    • Building the frequency map: O(n).
    • Processing elements: O(n) since we traverse the array once.
    • The overall time complexity is O(n log n) due to the sorting step.
  • Space Complexity:
    • O(n) for the frequency map and the original array.