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
Program to find shortest string after removing different adjacent bits in Python
Suppose we have a binary string s, we can delete any two adjacent letters if they are different. Finally, we have to find the length of the smallest string that we can get if we are able to perform this operation as many times as we want.
So, if the input is like s = "1100011", then the output will be 1, as after deleting "10" we get "10011", then again delete "10", it will be "011", then delete "01", it will have left "1".
Algorithm Approach
To solve this, we will follow these steps ?
- Create an empty stack
- For each character c in the string:
- If stack is empty or top of stack is same as c, then push c into stack
- Otherwise, when top of stack is different from c, pop element from stack
- Return the count of elements remaining in stack
How It Works
The stack-based approach works because when we encounter two different adjacent characters, they can be eliminated. The stack keeps track of characters that cannot be eliminated yet. When we find a different character, we can "cancel out" the previous one by popping from the stack.
Example
class Solution:
def solve(self, s):
stack = []
for c in s:
if not stack or stack[-1] == c:
stack.append(c)
elif stack[-1] != c:
stack.pop()
return len(stack)
# Test the solution
ob = Solution()
result = ob.solve("1100011")
print(f"Input: '1100011'")
print(f"Output: {result}")
Input: '1100011' Output: 1
Step-by-Step Execution
Let's trace through the algorithm with "1100011" ?
def solve_with_trace(s):
stack = []
print(f"Processing string: '{s}'")
for i, c in enumerate(s):
print(f"Step {i+1}: Processing '{c}', Stack: {stack}")
if not stack or stack[-1] == c:
stack.append(c)
print(f" ? Added '{c}' to stack: {stack}")
elif stack[-1] != c:
popped = stack.pop()
print(f" ? Removed '{popped}' from stack: {stack}")
print(f"Final stack length: {len(stack)}")
return len(stack)
solve_with_trace("1100011")
Processing string: '1100011' Step 1: Processing '1', Stack: [] ? Added '1' to stack: ['1'] Step 2: Processing '1', Stack: ['1'] ? Added '1' to stack: ['1', '1'] Step 3: Processing '0', Stack: ['1', '1'] ? Removed '1' from stack: ['1'] Step 4: Processing '0', Stack: ['1'] ? Removed '1' from stack: [] Step 5: Processing '0', Stack: [] ? Added '0' to stack: ['0'] Step 6: Processing '1', Stack: ['0'] ? Removed '0' from stack: [] Step 7: Processing '1', Stack: [] ? Added '1' to stack: ['1'] Final stack length: 1
Alternative Implementation
Here's a more concise version of the same algorithm ?
def shortest_string_length(s):
stack = []
for char in s:
if stack and stack[-1] != char:
stack.pop()
else:
stack.append(char)
return len(stack)
# Test with different examples
test_cases = ["1100011", "101010", "1111", ""]
for test in test_cases:
result = shortest_string_length(test)
print(f"Input: '{test}' ? Output: {result}")
Input: '1100011' ? Output: 1 Input: '101010' ? Output: 0 Input: '1111' ? Output: 4 Input: '' ? Output: 0
Time and Space Complexity
Time Complexity: O(n), where n is the length of the string, as we process each character once.
Space Complexity: O(n) in the worst case, when all characters are the same and no elimination occurs.
Conclusion
The stack-based approach efficiently simulates the elimination of different adjacent characters. The remaining stack size represents the shortest possible string length after all valid operations are performed.
