Facebook Pixel

1920. Build Array from Permutation

EasyArraySimulation
Leetcode Link

Problem Description

You are given a zero-based permutation array called nums. A zero-based permutation means the array contains all distinct integers from 0 to nums.length - 1 (inclusive).

Your task is to build a new array ans of the same length as nums, where each element at position i is constructed using the following rule:

  • ans[i] = nums[nums[i]]

In other words, for each index i:

  1. First, look at the value stored at nums[i]
  2. Use that value as an index to access nums again
  3. Store the resulting value in ans[i]

For example, if nums = [0, 2, 1, 5, 3, 4]:

  • For i = 0: nums[0] = 0, so ans[0] = nums[0] = 0
  • For i = 1: nums[1] = 2, so ans[1] = nums[2] = 1
  • For i = 2: nums[2] = 1, so ans[2] = nums[1] = 2
  • And so on...

The solution uses a simple list comprehension to iterate through each element num in nums and creates a new list where each element is nums[num]. This directly implements the required transformation ans[i] = nums[nums[i]].

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The problem asks us to perform a two-step lookup operation for each element. When we see ans[i] = nums[nums[i]], we can think of it as following a pointer chain:

  • Start at index i
  • Look up the value at that index to get nums[i]
  • Use that value as a new index to look up again

Since we're dealing with a zero-based permutation, we know that every value in nums is a valid index (ranging from 0 to nums.length - 1). This guarantees that nums[i] will always be a valid index to access the array again, so we won't run into index out of bounds errors.

The transformation is straightforward - we're essentially using each element as an indirect reference to another element. This is like saying "don't give me the value at position i, give me the value at the position that position i points to."

The most direct approach is to simply iterate through the array and apply this double-lookup operation for each position. We can elegantly express this using a list comprehension: [nums[num] for num in nums]. Here, num represents each value in the original array, and we use it as an index to look up nums[num].

This approach works in a single pass through the array, making it both time and implementation efficient. There's no need for complex logic or additional data structures - we just follow the problem's formula directly.

Solution Approach

The solution uses a direct simulation approach to construct the required array. We iterate through each element in the input array and apply the transformation rule ans[i] = nums[nums[i]].

Implementation Steps:

  1. Create a new array: We need to build a new array ans that will store our results. In Python, we can do this efficiently using a list comprehension.

  2. Apply the transformation: For each element in the original array:

    • Take the element value (let's call it num)
    • Use this value as an index to access nums[num]
    • Store the result in our new array

The Code Breakdown:

return [nums[num] for num in nums]

This list comprehension does the following:

  • for num in nums: Iterates through each element in the input array
  • nums[num]: Uses the current element value as an index to look up another value
  • [...]: Collects all these looked-up values into a new list

Example Walkthrough:

Let's trace through nums = [0, 2, 1, 5, 3, 4]:

  • When num = 0: nums[0] = 0 → add 0 to result
  • When num = 2: nums[2] = 1 → add 1 to result
  • When num = 1: nums[1] = 2 → add 2 to result
  • When num = 5: nums[5] = 4 → add 4 to result
  • When num = 3: nums[3] = 5 → add 5 to result
  • When num = 4: nums[4] = 3 → add 3 to result

Final result: [0, 1, 2, 4, 5, 3]

Time and Space Complexity:

  • Time: O(n) where n is the length of the input array, as we visit each element once
  • Space: O(n) for storing the output array (not counting the space for the output as extra space since it's required)

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a simple example with nums = [2, 0, 3, 1].

Step 1: Understand what we need to build

  • We need to create a new array where ans[i] = nums[nums[i]]
  • This means we do a double lookup: first get the value at index i, then use that value as an index

Step 2: Process each index

Let's trace through each position:

Index inums[i]nums[nums[i]]Explanation
02nums[2] = 3Look at position 0, find value 2, then look at position 2 to get 3
10nums[0] = 2Look at position 1, find value 0, then look at position 0 to get 2
23nums[3] = 1Look at position 2, find value 3, then look at position 3 to get 1
31nums[1] = 0Look at position 3, find value 1, then look at position 1 to get 0

Step 3: Build the result array

Following our list comprehension [nums[num] for num in nums]:

  • Iterate through values: [2, 0, 3, 1]
  • For value 2: get nums[2] = 3
  • For value 0: get nums[0] = 2
  • For value 3: get nums[3] = 1
  • For value 1: get nums[1] = 0

Final Result: ans = [3, 2, 1, 0]

Notice how we're using each element's value as an index to perform another lookup. Since this is a zero-based permutation, every value (0, 1, 2, 3) is guaranteed to be a valid index, so we'll never have an out-of-bounds error.

Solution Implementation

1class Solution:
2    def buildArray(self, nums: List[int]) -> List[int]:
3        """
4        Build an array where each element at index i is nums[nums[i]].
5      
6        Args:
7            nums: List of integers where each element is a valid index in the array
8      
9        Returns:
10            A new list where ans[i] = nums[nums[i]]
11        """
12        # Create a new array by using each element as an index to access another element
13        # For each element 'num' in nums, use it as an index to get nums[num]
14        return [nums[num] for num in nums]
15
1class Solution {
2    /**
3     * Builds a new array where each element at index i is nums[nums[i]].
4     * This creates a permutation based on the input array's values as indices.
5     * 
6     * @param nums Input array containing values in range [0, nums.length - 1]
7     * @return New array where ans[i] = nums[nums[i]]
8     */
9    public int[] buildArray(int[] nums) {
10        // Get the length of the input array
11        int n = nums.length;
12      
13        // Initialize result array with same length as input
14        int[] result = new int[n];
15      
16        // Iterate through each index in the input array
17        for (int i = 0; i < n; i++) {
18            // For each position i, set result[i] to the value at nums[nums[i]]
19            // This performs a two-level indexing operation
20            result[i] = nums[nums[i]];
21        }
22      
23        // Return the constructed array
24        return result;
25    }
26}
27
1class Solution {
2public:
3    /**
4     * Build a new array where each element at index i is nums[nums[i]]
5     * @param nums: input array where each element is a valid index
6     * @return: new array with transformed elements
7     */
8    vector<int> buildArray(vector<int>& nums) {
9        // Initialize result array to store the transformed elements
10        vector<int> result;
11      
12        // Iterate through each element in the input array
13        for (int i = 0; i < nums.size(); i++) {
14            // For each index i, add nums[nums[i]] to the result
15            // nums[i] gives us an index, then we use that index to get the final value
16            result.push_back(nums[nums[i]]);
17        }
18      
19        // Return the constructed array
20        return result;
21    }
22};
23
1/**
2 * Builds a new array where each element at index i is nums[nums[i]]
3 * @param nums - Input array where each element is a valid index within the array
4 * @returns New array with permuted values based on the input array indices
5 */
6function buildArray(nums: number[]): number[] {
7    // Map each element to the value at the index specified by that element
8    return nums.map((currentValue: number) => nums[currentValue]);
9}
10

Time and Space Complexity

Time Complexity: O(n), where n is the length of the array nums. The list comprehension iterates through each element in nums exactly once, and for each element, it performs a constant-time array access operation nums[num]. Therefore, the total time complexity is linear with respect to the input size.

Space Complexity: O(1) if we exclude the space required for the output array (as is standard practice when analyzing space complexity for problems that require returning a new array). The algorithm uses only a constant amount of extra space for the iteration variable num in the list comprehension. If we include the output array, the space complexity would be O(n) since we're creating a new array of the same size as the input.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Attempting In-Place Modification

A common mistake is trying to modify the array in-place, which leads to incorrect results because you're changing values that you still need to reference later.

Incorrect Approach:

def buildArray(self, nums: List[int]) -> List[int]:
    for i in range(len(nums)):
        nums[i] = nums[nums[i]]  # WRONG! Modifies values we still need
    return nums

Why it fails: When you update nums[0], you lose the original value that might be needed when processing later indices. For example, if nums[3] needs to reference the original nums[0], it will get the modified value instead.

Solution: Always create a new array for the result, or if you must modify in-place for space optimization, use a clever encoding technique (see advanced solution below).

2. Index Out of Bounds Concerns

While the problem guarantees a valid permutation (all values are between 0 and n-1), developers might add unnecessary bounds checking.

Overcomplicated Approach:

def buildArray(self, nums: List[int]) -> List[int]:
    result = []
    for num in nums:
        if 0 <= num < len(nums):  # Unnecessary check
            result.append(nums[num])
        else:
            result.append(0)  # Will never execute for valid input
    return result

Solution: Trust the problem constraints. The input is guaranteed to be a valid permutation, so every value will be a valid index.

3. Advanced: Space-Optimized In-Place Solution

If you need to solve this with O(1) extra space (modifying the original array), you can encode both old and new values in each position:

def buildArray(self, nums: List[int]) -> List[int]:
    n = len(nums)
  
    # First pass: encode both old and new values
    # new_value = nums[nums[i]], old_value = nums[i]
    # Store as: nums[i] = old_value + n * new_value
    for i in range(n):
        # Get the old value at nums[i] (might already be encoded)
        old_val = nums[nums[i]] % n
        nums[i] = nums[i] + n * old_val
  
    # Second pass: extract the new values
    for i in range(n):
        nums[i] = nums[i] // n
  
    return nums

This technique uses the fact that we can store two values in one integer by using division and modulo operations with the array length.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which of these properties could exist for a graph but not a tree?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More