Facebook Pixel

3379. Transformed Array

EasyArraySimulation
Leetcode Link

Problem Description

You are given an integer array nums that represents a circular array. Your task is to create a new array result of the same size, following these rules:

For each index i (where 0 <= i < nums.length), perform the following independent actions:

  • If nums[i] > 0: Start at index i and move nums[i] steps to the right in the circular array. Set result[i] to the value of the index where you land.
  • If nums[i] < 0: Start at index i and move abs(nums[i]) steps to the left in the circular array. Set result[i] to the value of the index where you land.
  • If nums[i] == 0: Set result[i] to nums[i].

Return the new array result.

Note: Since nums is circular, moving past the last element wraps around to the beginning, and moving before the first element wraps back to the end.

Intuition

To solve this problem, the primary challenge is dealing with the circular nature of the array. The problem requires moving either to the right or left based on the value at each position:

  1. Movement Direction: Determine the direction based on the sign of the integer at each index:

    • A positive number indicates movement to the right.
    • A negative number indicates movement to the left.
    • Zero results in no movement, and thus, the result at that position remains zero.
  2. Circular Wrapping: To handle the circular aspect, when you move beyond the array bounds, you wrap around to the other end. This can be efficiently managed using the modulus operator, which provides the remainder of a division. This remainder can be adjusted to fit within the bounds of the array indices, hence facilitating circular movement.

  3. Implementation Strategy:

    • For each element in the array, determine the number of steps and the direction. Compute the destination index by adding the number of steps to your current index.
    • Adjust the calculated index using (current_index + steps + n) % n, where n is the length of the array, ensuring the index wraps around correctly within array bounds.
    • Use this index to fetch the new value from nums and set it in the result array.

This approach ensures each element is processed individually and efficiently while managing the circular nature of the array using mathematical computation with modulus operations.

Solution Approach

The solution approach involves a straightforward implementation that utilizes a single pass through the nums array with the help of mathematical operations. Here's how it works:

  1. Initialize Variables:

    • Create an empty list ans that will store the results.
    • Determine the length of the array n using len(nums).
  2. Iterate Through the Array:

    • Use a for loop with enumerate(nums) to access both the index i and the element x at that index.
    • For each element, determine the action based on its value:
      • Positive Value (nums[i] > 0):
        • Compute the destination index using (i + nums[i] + n) % n. This ensures that moving to the right, even beyond the array's end, wraps around using the modulus operator.
        • Append the value at this new index to ans.
      • Negative Value (nums[i] < 0):
        • Compute the destination index using (i + nums[i] + n) % n. Here, the movement is to the left, and the modulus operator ensures no negative indices occur.
        • Append the value at this calculated index to ans.
      • Zero Value (nums[i] == 0):
        • Directly append 0 to ans since no movement is required.
  3. Return the Result:

    • Once the loop completes, the list ans contains the transformed array as required by the problem. Return ans as the output.

The overall complexity of this solution is O(n) due to the single pass through the array with constant-time operations, making it efficient for large datasets.

Ready to land your dream job?

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

Start Evaluator

Example Walkthrough

Consider the integer array nums = [2, -1, 3, 0]. We need to construct a new array result following the circular movement rules for each element in nums. Let's work through each index step-by-step:

  1. Index 0 (nums[0] = 2):

    • Since nums[0] is positive, we move 2 steps to the right.
    • Calculate the new index: (0 + 2 + 4) % 4 = 2.
    • nums[2] is 3, so set result[0] to 3.
  2. Index 1 (nums[1] = -1):

    • Since nums[1] is negative, move 1 step to the left.
    • Calculate the new index: (1 - 1 + 4) % 4 = 0.
    • nums[0] is 2, so set result[1] to 2.
  3. Index 2 (nums[2] = 3):

    • Since nums[2] is positive, we move 3 steps to the right.
    • Calculate the new index: (2 + 3 + 4) % 4 = 1.
    • nums[1] is -1, so set result[2] to -1.
  4. Index 3 (nums[3] = 0):

    • Since nums[3] is zero, no movement is needed.
    • Directly set result[3] to 0.

After processing each index, the result array becomes [3, 2, -1, 0].

This example illustrates how the solution approach effectively handles each element in a circular manner, calculating the correct index using modulus arithmetic and populating the result array accordingly.

Solution Implementation

1from typing import List
2
3class Solution:
4    def constructTransformedArray(self, nums: List[int]) -> List[int]:
5        # Initialize an empty list to hold the transformed values
6        transformed_array = []
7      
8        # Get the length of the input list 'nums'
9        n = len(nums)
10      
11        # Iterate through the list 'nums' with both index 'i' and element 'x'
12        for i, x in enumerate(nums):
13            # Calculate the new index for each element and append the result
14            # If x is zero, append 0 to the transformed list
15            transformed_array.append(nums[(i + x + n) % n] if x != 0 else 0)
16      
17        # Return the constructed transformed array
18        return transformed_array
19
1class Solution {
2    public int[] constructTransformedArray(int[] nums) {
3        int n = nums.length;
4        // Initialize an array to hold the transformed results
5        int[] transformedArray = new int[n];
6
7        // Iterate over each element in the input array
8        for (int i = 0; i < n; ++i) {
9            // If the current element is not zero, calculate the new index
10            // and assign the value from the original array to the result array
11            // Computation: (i + nums[i] % n + n) % n ensures a valid index in bounds
12            transformedArray[i] = nums[i] != 0 ? nums[(i + nums[i] % n + n) % n] : 0;
13        }
14
15        // Return the transformed array
16        return transformedArray;
17    }
18}
19
1#include <vector>
2using namespace std;
3
4class Solution {
5public:
6    vector<int> constructTransformedArray(vector<int>& nums) {
7        int n = nums.size();  // Get the size of the input vector
8        vector<int> ans(n);   // Initialize the result vector with the same size as nums
9
10        for (int i = 0; i < n; ++i) {
11            if (nums[i] != 0) {
12                // Compute the new index by adding the modulus of the value with n, ensuring it's positive
13                int newIndex = (i + nums[i] % n + n) % n;
14                ans[i] = nums[newIndex];  // Assign the value from the computed index
15            } else {
16                ans[i] = 0;  // Assign 0 if the current element is 0
17            }
18        }
19        return ans;  // Return the transformed vector
20    }
21};
22
1// The function `constructTransformedArray` transforms an array `nums` based on a specific rule.
2function constructTransformedArray(nums: number[]): number[] {
3    // Get the length of the input array `nums`.
4    const n = nums.length;
5  
6    // Initialize an empty array to store the transformed values.
7    const ans: number[] = [];
8  
9    // Iterate through each element in the input array `nums`.
10    for (let i = 0; i < n; ++i) {
11        // If `nums[i]` is not zero, compute the new index using modulo and offset logic, otherwise push 0.
12        // The new index is calculated as the current index plus `nums[i]` modulo `n`, 
13        // adjusted with `+ n` to ensure a positive result and again modulo `n` to wrap around.
14        ans.push(nums[i] ? nums[(i + (nums[i] % n) + n) % n] : 0);
15    }
16  
17    // Return the transformed array.
18    return ans;
19}
20

Time and Space Complexity

The time complexity of the given code is O(n) where n is the length of the input list nums. This is because the algorithm iterates over the list nums exactly once, performing a constant amount of work for each element.

The space complexity is also O(n). This is due to the creation of the list ans which contains the transformed elements of the list nums, and ans will have the same length as nums.

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


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

What's the output of running the following function using input [30, 20, 10, 100, 33, 12]?

1def fun(arr: List[int]) -> List[int]:
2    import heapq
3    heapq.heapify(arr)
4    res = []
5    for i in range(3):
6        res.append(heapq.heappop(arr))
7    return res
8
1public static int[] fun(int[] arr) {
2    int[] res = new int[3];
3    PriorityQueue<Integer> heap = new PriorityQueue<>();
4    for (int i = 0; i < arr.length; i++) {
5        heap.add(arr[i]);
6    }
7    for (int i = 0; i < 3; i++) {
8        res[i] = heap.poll();
9    }
10    return res;
11}
12
1class HeapItem {
2    constructor(item, priority = item) {
3        this.item = item;
4        this.priority = priority;
5    }
6}
7
8class MinHeap {
9    constructor() {
10        this.heap = [];
11    }
12
13    push(node) {
14        // insert the new node at the end of the heap array
15        this.heap.push(node);
16        // find the correct position for the new node
17        this.bubble_up();
18    }
19
20    bubble_up() {
21        let index = this.heap.length - 1;
22
23        while (index > 0) {
24            const element = this.heap[index];
25            const parentIndex = Math.floor((index - 1) / 2);
26            const parent = this.heap[parentIndex];
27
28            if (parent.priority <= element.priority) break;
29            // if the parent is bigger than the child then swap the parent and child
30            this.heap[index] = parent;
31            this.heap[parentIndex] = element;
32            index = parentIndex;
33        }
34    }
35
36    pop() {
37        const min = this.heap[0];
38        this.heap[0] = this.heap[this.size() - 1];
39        this.heap.pop();
40        this.bubble_down();
41        return min;
42    }
43
44    bubble_down() {
45        let index = 0;
46        let min = index;
47        const n = this.heap.length;
48
49        while (index < n) {
50            const left = 2 * index + 1;
51            const right = left + 1;
52
53            if (left < n && this.heap[left].priority < this.heap[min].priority) {
54                min = left;
55            }
56            if (right < n && this.heap[right].priority < this.heap[min].priority) {
57                min = right;
58            }
59            if (min === index) break;
60            [this.heap[min], this.heap[index]] = [this.heap[index], this.heap[min]];
61            index = min;
62        }
63    }
64
65    peek() {
66        return this.heap[0];
67    }
68
69    size() {
70        return this.heap.length;
71    }
72}
73
74function fun(arr) {
75    const heap = new MinHeap();
76    for (const x of arr) {
77        heap.push(new HeapItem(x));
78    }
79    const res = [];
80    for (let i = 0; i < 3; i++) {
81        res.push(heap.pop().item);
82    }
83    return res;
84}
85

Recommended Readings

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


Load More