class Solution:
def buildArray(self, target, n):
res = []
curr = 1
i = 0
while i < len(target):
if curr == target[i]:
res.append("Push")
i += 1
else:
res.append("Push")
res.append("Pop")
curr += 1
return res
class Solution {
public:
vector<string> buildArray(vector<int>& target, int n) {
vector<string> res;
int curr = 1, i = 0;
while (i < target.size()) {
if (curr == target[i]) {
res.push_back("Push");
++i;
} else {
res.push_back("Push");
res.push_back("Pop");
}
++curr;
}
return res;
}
};
class Solution {
public List<String> buildArray(int[] target, int n) {
List<String> res = new ArrayList<>();
int curr = 1, i = 0;
while (i < target.length) {
if (curr == target[i]) {
res.add("Push");
i++;
} else {
res.add("Push");
res.add("Pop");
}
curr++;
}
return res;
}
}
var buildArray = function(target, n) {
let res = [];
let curr = 1, i = 0;
while (i < target.length) {
if (curr === target[i]) {
res.push("Push");
i++;
} else {
res.push("Push");
res.push("Pop");
}
curr++;
}
return res;
};
You are given a strictly increasing array target containing integers from 1 to n (inclusive), and an integer n. You have an empty stack and can perform two operations: Push (add the next number in sequence from 1 to n onto the stack), and Pop (remove the top element from the stack). Your goal is to build the target array by simulating these stack operations in order, starting from 1 up to n (but you may stop early if target is completed).
For each number from 1 to n:
target, you must Push it onto the stack.target, you must Push it and then immediately Pop it.target array. Each number from 1 to n can be used at most once and in order. The solution is unique.
At first glance, you might consider simulating the stack fully, pushing and popping values as needed, or even trying to generate all possible sequences. However, the problem's constraints and the strictly increasing property of target mean that for each value from 1 to n, you know exactly what to do:
target, you Push it and move to the next target value.
This leads to a direct and efficient solution, where you only need to iterate through numbers from 1 up to the last value in target (since all target values are between 1 and n).
Let's break down the solution step by step:
target array. Start a counter at 1 to represent the next number to consider.
target[-1] (the largest number in target):
target value, append "Push" to the result and move to the next target value.target are processed, you can stop. There's no need to continue up to n.
This approach is both simple and efficient because it leverages the properties of the input: strictly increasing and unique values in target.
Let's walk through an example with target = [2, 3, 4] and n = 4:
target[0] = 2, so 1 is not in target.target[0] = 2, so 2 is in target.target[1] = 3, so 3 is in target.target[2] = 4, so 4 is in target.So the output would be: ["Push", "Pop", "Push", "Push", "Push"].
Brute-force approach: If you tried to generate all possible stack operation sequences, the time and space complexity would be exponential, which is infeasible for even moderate values of n.
Optimized approach (used here):
target. This is because we only process numbers up to target[-1], and at each step we do a constant amount of work.target (in the case where every non-target element is pushed and popped).
The key insight is to leverage the strictly increasing nature of target and the requirement to process numbers in order from 1 to n. By comparing each number with the next target value, we can efficiently decide whether to "Push" or "Push" and "Pop". This direct approach avoids unnecessary simulation and results in a simple, efficient, and elegant solution.