Problem
Given a permutation $(P_1, P_2, \ldots, P_n)$ of the numbers (1, 2, \ldots, n), determine whether it is possible to obtain this permutation using a stack. The permutation is valid if and only if there are no indices (i < j < k) such that (P_j < P_k < P_i).
Examples
Example 1:
Input: 3
Output: 5
Explanation: There are 5 valid permutations for 3 distinct characters, as given by the 3rd Catalan number (C_n).
Example 2:
Input: 4
Output: 14
Explanation: There are 14 valid permutations for 4 distinct characters, as given by the 4th Catalan number (C_n).
Solution
Method 1 - Using Stack
To validate if a permutation can be obtained from a stack, we need to check for the condition (i < j < k) such that (P_j < P_k < P_i). This specific condition indicates that the values violate the sequence of stack operations.
- A stack works on a last-in, first-out (LIFO) basis.
- As you push elements to get to (P_i), elements (P_j) and (P_k) must appear in the correct order to abide by the stack properties.
- The condition (P_j < P_k < P_i) violates the stack property as (P_j) should have been out before (P_k) if (P_k) is expected to come out before (P_i).
Approach
- Use a stack data structure to simulate the behavior of generating the permutation from the sequence.
- Traverse the permutation and use the stack to manage the smallest elements at any point.
- Ensure that no index triplet violates the given condition.
Code
Java
public class Solution {
public boolean canObtainPermutation(int[] permutation) {
Stack<Integer> stack = new Stack<>();
int lowestPossibleValue = Integer.MAX_VALUE;
for (int value : permutation) {
if (value > lowestPossibleValue) {
while (!stack.isEmpty() && stack.peek() < value) {
lowestPossibleValue = stack.pop();
}
}
stack.push(value);
}
return true;
}
// Example usage
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.canObtainPermutation(new int[]{1, 2, 3})); // Output: True
System.out.println(solution.canObtainPermutation(new int[]{3, 1, 2})); // Output: False
}
}
Python
class Solution:
def can_obtain_permutation(self, permutation):
stack = []
lowest_possible_value = float('inf')
for value in permutation:
if value > lowest_possible_value:
while stack and stack[-1] < value:
lowest_possible_value = stack.pop()
stack.append(value)
return True
# Example usage
solution = Solution()
print(solution.can_obtain_permutation([1, 2, 3])) # Output: True
print(solution.can_obtain_permutation([3, 1, 2])) # Output: False
Complexity
- ⏰ Time complexity:
O(n)
—since we only traverse the permutation once. - 🧺 Space complexity:
O(n)
—due to the usage of stack space depending on the input size.