Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Check if moves in a stack or queue are possible or nots in Python
Stack and queue operations follow a specific order where elements must be pushed before they can be popped. Given a binary list where 1 represents a push operation and 0 represents a pop operation, we need to validate if the sequence of operations is possible without attempting to pop from an empty structure.
Problem Understanding
The key insight is that at any point during the operations, the number of pop operations cannot exceed the number of push operations. If we encounter more pops than pushes, we're trying to remove elements from an empty stack or queue, which is invalid.
Algorithm
We maintain a counter to track the balance between push and pop operations ?
- Initialize
push_countto 0 - For each operation in the sequence:
- If operation is 1 (push), increment the counter
- If operation is 0 (pop), decrement the counter
- If counter becomes negative, return False (invalid sequence)
- Return True if all operations are processed without going negative
Implementation
def solve(nums):
push_count = 0
for i in range(len(nums)):
if nums[i]:
push_count += 1
else:
push_count -= 1
if push_count < 0:
return False
return True
# Test with example
nums = [1,0,1,1,0,1]
print("Operations:", nums)
print("Valid sequence:", solve(nums))
Operations: [1, 0, 1, 1, 0, 1] Valid sequence: True
Step-by-step Trace
Let's trace through the example [1,0,1,1,0,1] ?
def solve_with_trace(nums):
push_count = 0
print("Step | Operation | Counter | Valid")
print("-" * 35)
for i, op in enumerate(nums):
if op:
push_count += 1
operation = "Push"
else:
push_count -= 1
operation = "Pop"
valid = "Yes" if push_count >= 0 else "No"
print(f"{i+1:4} | {operation:9} | {push_count:7} | {valid}")
if push_count < 0:
return False
return True
nums = [1,0,1,1,0,1]
result = solve_with_trace(nums)
print(f"\nFinal result: {result}")
Step | Operation | Counter | Valid ----------------------------------- 1 | Push | 1 | Yes 2 | Pop | 0 | Yes 3 | Push | 1 | Yes 4 | Push | 2 | Yes 5 | Pop | 1 | Yes 6 | Push | 2 | Yes Final result: True
Invalid Example
Here's an example of an invalid sequence ?
# Invalid sequence - trying to pop from empty structure
invalid_nums = [0,1,0,0,1]
print("Operations:", invalid_nums)
print("Valid sequence:", solve(invalid_nums))
# Trace the invalid sequence
print("\nTracing invalid sequence:")
solve_with_trace(invalid_nums)
Operations: [0, 1, 0, 0, 1] Valid sequence: False Tracing invalid sequence: Step | Operation | Counter | Valid ----------------------------------- 1 | Pop | -1 | No Final result: False
Time and Space Complexity
- Time Complexity: O(n) where n is the length of the input list
- Space Complexity: O(1) as we only use a single counter variable
Conclusion
This algorithm efficiently validates stack or queue operation sequences by maintaining a running count of push-pop balance. The key insight is that the counter should never go negative, ensuring we never attempt to pop from an empty structure.
