Given a zero-based permutation nums (0-indexed), build an array ans of the same length where ans[i] = nums[nums[i]] for each 0 <= i < nums.length and return it.
A zero-based permutation nums is an array of distinct integers from 0 to nums.length - 1 (inclusive).
Example 1:
Input: nums = [0,2,1,5,3,4]
Output: [0,1,2,4,5,3]
Explanation: The array ans is built as follows:
ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]]
= [nums[0], nums[2], nums[1], nums[5], nums[3], nums[4]]
= [0,1,2,4,5,3]
Example 2:
Input: nums = [5,0,1,2,3,4]
Output: [4,5,0,1,2,3]
Explanation: The array ans is built as follows:
ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]]
= [nums[5], nums[0], nums[1], nums[2], nums[3], nums[4]]
= [4,5,0,1,2,3]
Constraints:
1 <= nums.length <= 10000 <= nums[i] < nums.lengthnums are distinct.Follow-up: Can you solve it without using an extra space (i.e., O(1) memory)?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach constructs a new arrangement by looking at each existing value and using it to find a corresponding value in the original arrangement. We create the new arrangement element by element based on the relationship given.
Here's how the algorithm would work step-by-step:
def build_array_from_permutation(numbers):
array_length = len(numbers)
new_array = [0] * array_length
for index in range(array_length):
# Find the value at the current index.
value_at_index = numbers[index]
# Use that value as an index to find the corresponding value.
new_array[index] = numbers[value_at_index]
return new_arrayThe goal is to create a new arrangement of numbers based on an initial arrangement. The clever approach is to encode both the old and new values in the original arrangement, then extract the new values in a second step. This avoids using extra storage.
Here's how the algorithm would work step-by-step:
def build_array_from_permutation(nums):
number_of_elements = len(nums)
# Encode both the new and old values into the array.
for index in range(number_of_elements):
nums[index] += number_of_elements * (nums[nums[index]] % number_of_elements)
# Extract the new values after encoding.
for index in range(number_of_elements):
# Shift encoded values to their correct position.
nums[index] //= number_of_elements
return nums| Case | How to Handle |
|---|---|
| Null or empty input array | Return an empty array or throw an IllegalArgumentException, depending on desired behavior. |
| Input array with a single element | The algorithm should work correctly since ans[0] = nums[nums[0]]. |
| Large input array (n close to the maximum integer value) | Ensure the index calculations and memory allocation for the 'ans' array don't cause integer overflow or memory exhaustion. |
| Input array contains values that are out of bounds (i.e., nums[i] >= n or nums[i] < 0) | Throw an IllegalArgumentException because the index access would result in an ArrayIndexOutOfBoundsException. |
| Input array contains duplicate values and the permutation contains cycles | The standard algorithm directly calculates the new array and handles cycles by design, without any explicit checks. |
| Input array where nums[i] == i for all i (identity permutation) | The algorithm correctly computes ans[i] = nums[nums[i]] = nums[i], effectively returning the same array. |
| Integer overflow when accessing nums[nums[i]] | Ensure the data type used for indexing can handle the maximum possible value of 'n' to prevent integer overflow. |
| Input array is a valid permutation, but creating 'ans' requires excessive memory | Consider in-place manipulation (if allowed and safe) or streaming/chunking for extremely large arrays to reduce memory footprint, otherwise throw OutOfMemoryError. |