diff --git a/DIRECTORY.md b/DIRECTORY.md index 0880b19a..0ac30eec 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -268,6 +268,8 @@ * Binary Search * Divide Chocolate * [Test Divide Chocolate](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/search/binary_search/divide_chocolate/test_divide_chocolate.py) + * Magnetic Force Between Two Balls + * [Test Magnetic Force Between Two Balls](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/search/binary_search/magnetic_force_between_two_balls/test_magnetic_force_between_two_balls.py) * Maxruntime N Computers * [Test Max Runtime](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/search/binary_search/maxruntime_n_computers/test_max_runtime.py) * Split Array Largest Sum @@ -312,11 +314,16 @@ * Stack * Daily Temperatures * [Test Daily Temperatures](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/stack/daily_temperatures/test_daily_temperatures.py) + * Minimum String Length After Removing Substrings + * [Test Min Str Length After Removing Substrings](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/stack/minimum_string_length_after_removing_substrings/test_min_str_length_after_removing_substrings.py) * Taxi Numbers * [Taxi Numbers](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/taxi_numbers/taxi_numbers.py) * Top K Elements * Smallest Range Covering K Lists * [Test Smallest Range Covering Elements From K Lists](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/top_k_elements/smallest_range_covering_k_lists/test_smallest_range_covering_elements_from_k_lists.py) + * Trie + * Longest Word With Prefixes + * [Test Longest Word With Prefixes](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/trie/longest_word_with_prefixes/test_longest_word_with_prefixes.py) * Two Pointers * Array 3 Pointers * [Test Array 3 Pointers](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/two_pointers/array_3_pointers/test_array_3_pointers.py) @@ -440,6 +447,8 @@ * [Test Sub Array With Sum](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/sub_array_with_sum/test_sub_array_with_sum.py) * Subarrays With Fixed Bounds * [Test Subarrays With Fixed Bounds](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/subarrays_with_fixed_bounds/test_subarrays_with_fixed_bounds.py) + * Bloom Filter + * [Bloom Filter](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/bloom_filter/bloom_filter.py) * Circular Buffer * [Circular Buffer](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/circular_buffer/circular_buffer.py) * [Exceptions](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/circular_buffer/exceptions.py) diff --git a/algorithms/search/binary_search/magnetic_force_between_two_balls/README.md b/algorithms/search/binary_search/magnetic_force_between_two_balls/README.md new file mode 100644 index 00000000..4e93defc --- /dev/null +++ b/algorithms/search/binary_search/magnetic_force_between_two_balls/README.md @@ -0,0 +1,53 @@ +# Magnetic Force Between Two Balls + +In the universe Earth C-137, Rick discovered a special form of magnetic force between two balls if they are put in his +new invented basket. Rick has n empty baskets, the ith basket is at position[i], Morty has m balls and needs to distribute +the balls into the baskets such that the minimum magnetic force between any two balls is maximum. + +Rick stated that magnetic force between two different balls at positions x and y is |x - y|. + +Given the integer array position and the integer m. Return the required force i.e. the maximum possible value of the +minimum magnetic force between any two balls after they have been placed in the baskets. + +## Examples + +Example: +![Example 1](./images/examples/magnetic_force_between_two_balls_example_1.png) + +```text +Input: position = [1,2,3,4,7], m = 3 +Output: 3 +Explanation: Distributing the 3 balls into baskets 1, 4 and 7 will make the magnetic force between ball pairs [3, 3, 6]. +The minimum magnetic force is 3. We cannot achieve a larger minimum magnetic force than 3 +``` + +```text +Input: position = [5,4,3,2,1,1000000000], m = 2 +Output: 999999999 +Explanation: We can use baskets 1 and 1000000000. +``` + +![Example 2](./images/examples/magnetic_force_between_two_balls_example_2.png) +![Example 3](./images/examples/magnetic_force_between_two_balls_example_3.png) +![Example 4](./images/examples/magnetic_force_between_two_balls_example_4.png) + + +## Constraints + +- n == `position.length` +- 2 <= n <= 10^5 +- 1 <= position[i] <= 10^9 +- All integers in `position` are distinct. +- 2 <= `m` <= `position.length` + +## Topics + +- Array +- Binary Search +- Sorting + +## Hints + +- If you can place balls such that the answer is x then you can do it for y where y < x. +- Similarly if you cannot place balls such that the answer is x then you cannot do it for y where y > x. +- Binary search on the answer and greedily see if it is possible. diff --git a/algorithms/search/binary_search/magnetic_force_between_two_balls/__init__.py b/algorithms/search/binary_search/magnetic_force_between_two_balls/__init__.py new file mode 100644 index 00000000..42d5e1a3 --- /dev/null +++ b/algorithms/search/binary_search/magnetic_force_between_two_balls/__init__.py @@ -0,0 +1,50 @@ +from typing import List + + +def max_distance(position: List[int], m: int) -> int: + if not position: + return 0 + if m <= 1: + return 0 + + result = 0 + n = len(position) + sorted_positions = sorted(position) + + # initial search space + low = 1 + high = int(sorted_positions[-1] / (m - 1.0)) + 1 + + def can_place_balls(x: int) -> bool: + """Check if we can place 'm' balls at 'position' with each ball having at least 'x' gap.""" + + # place first ball at the first positions + prev_ball_position = sorted_positions[0] + balls_placed = 1 + + # Iterate on each position and place a ball there if we can place it + for i in range(1, n): + current_position = sorted_positions[i] + # check if we can place the ball at the current position + if current_position - prev_ball_position >= x: + balls_placed += 1 + prev_ball_position = current_position + # if all m balls are placed return true + if balls_placed == m: + return True + + return False + + while low <= high: + mid = low + (high - low) // 2 + # if we can place all balls having a gap at least mid + if can_place_balls(mid): + # Then mid can be our answer + result = mid + # and discard the left-half search space + low = mid + 1 + else: + # discard the right-half search space + high = mid - 1 + + return result diff --git a/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_1.png b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_1.png new file mode 100644 index 00000000..5c00a9a1 Binary files /dev/null and b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_1.png differ diff --git a/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_2.png b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_2.png new file mode 100644 index 00000000..29229071 Binary files /dev/null and b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_2.png differ diff --git a/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_3.png b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_3.png new file mode 100644 index 00000000..5de52f31 Binary files /dev/null and b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_3.png differ diff --git a/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_4.png b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_4.png new file mode 100644 index 00000000..c0f2c520 Binary files /dev/null and b/algorithms/search/binary_search/magnetic_force_between_two_balls/images/examples/magnetic_force_between_two_balls_example_4.png differ diff --git a/algorithms/search/binary_search/magnetic_force_between_two_balls/test_magnetic_force_between_two_balls.py b/algorithms/search/binary_search/magnetic_force_between_two_balls/test_magnetic_force_between_two_balls.py new file mode 100644 index 00000000..5fa700f9 --- /dev/null +++ b/algorithms/search/binary_search/magnetic_force_between_two_balls/test_magnetic_force_between_two_balls.py @@ -0,0 +1,27 @@ +import unittest +from typing import List +from parameterized import parameterized +from algorithms.search.binary_search.magnetic_force_between_two_balls import ( + max_distance, +) + +MAGNETIC_FORCE_BETWEEN_TWO_BALLS_TEST_CASES = [ + ([1, 2, 3, 4, 7], 3, 3), + ([5, 4, 3, 2, 1, 1000000000], 2, 999999999), + ([1, 2, 3, 7, 11], 2, 10), + ([9, 8, 7, 3], 3, 2), + ([1, 3, 7, 9, 14], 5, 2), + ([1000, 1], 2, 999), + ([5, 10, 15, 20, 25, 30], 4, 5), +] + + +class MagneticForceBetweenTwoBallsTestCase(unittest.TestCase): + @parameterized.expand(MAGNETIC_FORCE_BETWEEN_TWO_BALLS_TEST_CASES) + def test_max_distance(self, position: List[int], m: int, expected: int): + actual = max_distance(position, m) + self.assertEqual(expected, actual) + + +if __name__ == "__main__": + unittest.main() diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/README.md b/algorithms/stack/minimum_string_length_after_removing_substrings/README.md new file mode 100644 index 00000000..25204bc3 --- /dev/null +++ b/algorithms/stack/minimum_string_length_after_removing_substrings/README.md @@ -0,0 +1,219 @@ +# Minimum String Length After Removing Substrings + +You are given a string s consisting only of uppercase English letters. + +You can apply some operations to this string where, in one operation, you can remove any occurrence of one of the +substrings "AB" or "CD" from s. + +Return the minimum possible length of the resulting string that you can obtain. + +Note that the string concatenates after removing the substring and could produce new "AB" or "CD" substrings. + +## Examples + +![Example 1](./images/examples/minimum_string_length_after_removing_substrings_example_1.png) +![Example 2](./images/examples/minimum_string_length_after_removing_substrings_example_2.png) +![Example 3](./images/examples/minimum_string_length_after_removing_substrings_example_3.png) + +Example 4: + +```text +Input: s = "ABFCACDB" +Output: 2 +Explanation: We can do the following operations: +- Remove the substring "AB", so s = "FCACDB". +- Remove the substring "CD", so s = "FCAB". +- Remove the substring "AB", so s = "FC". +So the resulting length of the string is 2. +It can be shown that it is the minimum length that we can obtain. +``` + +Example 5: + +```text +Input: s = "ACBBD" +Output: 5 +Explanation: We cannot do any operations on the string so the length remains the same. +``` + +## Constraints + +- 1 ≤ `s.length` ≤ 100 +- s consists only of uppercase English letters. + +## Topics + +- String +- Stack +- Simulation + +## Hints + +- Can we use brute force to solve the problem? +- Repeatedly traverse the string to find and remove the substrings “AB” and “CD” until no more occurrences exist. +- Can the solution be optimized using a stack? + +## Solution(s) + +1. [String Replace](#string-replace) +2. [Stack](#stack) +3. [In Place Manipulation](#in-place-manipulation) + +### String Replace + +The core issue with this problem is the ripple effect of removing substrings. When we delete one occurrence of "AB" or +"CD", it can create another substring that also needs removal. For example, in "CABD", if we remove "AB", we are left +with "CD", which must also be eliminated to minimize the string length. + +A brute force approach will be to continuously check the string for "AB" and "CD" and remove them until none are left. +Once the loop ends, the string will have no remaining "AB" or "CD", and we can return its length. Many programming +languages offer built-in functions for finding and removing substrings, which will be helpful here. + +> Note: Some programming practices suggest avoiding direct modifications to input data. If this applies, consider +> making a copy of the input string before you start. It’s a good idea to clarify this with your interviewer before you +> implement the solution. + +**Algorithm** + +- Enter a loop that continues while s contains either "AB" or "CD". + - Check if s contains "AB": + - If "AB" is present, remove all occurrences of "AB" from s. + - If "AB" is not present, check if s contains "CD". + - If "CD" is present, remove all occurrences of "CD" from s. +- After the loop ends, return the length of s. + +#### Complexity Analysis + +Let `n` be the length of the input string `s`. + +##### Time Complexity + +The outer while loop can run up to `n/2` times in the worst case. This occurs when we remove two characters in each +iteration (e.g., for a string like "ABABABAB"). Inside the loop, the string methods need to scan the entire string, +which takes O(n) time. + +Thus, the overall time complexity of the algorithm is `O(n/2⋅n)=O(n^2)`. + +##### Space Complexity + +In Python3 and Java, strings are immutable. So, each string operation creates a new string object. However, at any given +time, we only need to store one version of the processed string. So, the space complexity is `O(n)`. + +However, in C++, strings are mutable. So, string operations like erase() are performed in place. Thus, the space +complexity in C++ is `O(1)`. + +### Stack + +In the string removal process, we face two choices for each character: + +- Keep the character if it does not form a removable pattern. +- Remove it along with the previous character if it completes a pattern. + +Using a stack simplifies this task. We push characters onto the stack as we read them and pop them off when we find a +pattern. + +We read the input string from left to right. For each character, we decide to either add it to the stack or remove a +previous character. If the stack is not empty, we compare the current character with the top character on the stack. +If they form "AB" or "CD," we pop the stack. We do not push the current character, thus removing both characters. If +there is no pattern, we push the current character onto the stack. + +After processing all characters, the remaining elements in the stack represent the minimum length of the string after +all possible removals. + +**Algorithm** + +- Initialize a stack to store the characters from the string. +- Iterate over each character in the input string s. For each character currentChar: + - If the stack is empty, push currentChar onto the stack and continue to the next character. + - If the current character is 'B' and the top of the stack is 'A', remove the top element from the stack. + - If the current character is 'D' and the top of the stack is 'C', remove the top element from the stack. + - If neither of the above conditions is met, push currentChar onto the stack. +- After processing all characters, return the size of the stack. + +![Solution 1](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_1.png) +![Solution 2](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_2.png) +![Solution 3](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_3.png) +![Solution 4](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_4.png) +![Solution 5](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_5.png) +![Solution 6](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_6.png) +![Solution 7](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_7.png) +![Solution 8](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_8.png) +![Solution 9](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_9.png) +![Solution 10](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_10.png) +![Solution 11](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_11.png) +![Solution 12](./images/solutions/minimum_string_length_after_removing_substrings_stack_solution_12.png) + +#### Complexity Analysis + +Let `n` be the length of the input string `s`. + +##### Time Complexity + +We iterate over each character of s exactly once. All stack operations inside the loop take constant time. Thus, the +time complexity of the algorithm is `O(n)`. + +##### Space Complexity + +We use a stack to store characters from the input string. In the worst-case scenario, where no "AB" or "CD" patterns are +found, we would end up storing all n characters in the stack. Thus, the space complexity of the algorithm is `O(n)`. + +### In Place Manipulation + +To optimize space, we can modify the string in place. + +We use two pointers: + +- Read Pointer (readPtr): This pointer moves from left to right through the string, checking each character. +- Write Pointer (writePtr): This pointer tracks where to write the next character we want to keep. + +We start by setting writePtr to 0. As we move readPtr through the string, we copy the character at readPtr to the +position indicated by writePtr. Next, we check if the last two characters (positions writePtr-1 and writePtr) form a +removable pattern, such as "AB" or "CD". If they do, we decrease writePtr, which means we will overwrite this part in +the next steps. + +If the last two characters do not form a removable pattern, we increment writePtr to point to the next position where +we can write a character. This way, we can effectively "remove" unwanted characters by overwriting them. + +After processing all characters, the position of writePtr tells us the length of the final string. All the characters +we want to keep are now at the beginning of the array, up to the position of writePtr. + +![Solution 1](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_1.png) +![Solution 2](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_2.png) +![Solution 3](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_3.png) +![Solution 4](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_4.png) +![Solution 5](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_5.png) +![Solution 6](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_6.png) +![Solution 7](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_7.png) +![Solution 8](./images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_8.png) + +**Algorithm** + +- Initialize a variable writePtr to 0, which will keep track of the current write position. +- Iterate over each character in the string using a readPtr: + - Copy the character at readPtr to the position at writePtr in the string. + - Check if the following conditions are met: + - writePtr is greater than 0 (ensuring there's a previous character). + - The previous character (at writePtr - 1) is either 'A' or 'C'. + - The current character is exactly one ASCII value higher than the previous character. + - If these conditions are met: + - Decrement writePtr by 1, effectively removing the pair of characters. + - Else: + - Increment writePtr by 1, moving to the next position for writing. +- Return the value of writePtr, which represents the length of the remaining string after all removals. + +#### Complexity Analysis + +Let `n` be the length of the input string `s`. + +##### Time Complexity + +We iterate through the input string exactly once. All operations within the loop take constant time. Thus, the overall +time complexity is linear, `O(n)`. + +##### Space Complexity + +In Java and Python3, strings are immutable. So, the input string needs to be converted to an array or list to perform in +place modifications. Thus, the space complexity remains O(n). + +String are mutable in C++. So, all modifications can be done on the input string itself. No additional data structures +are used, so the space complexity is O(1). diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/__init__.py b/algorithms/stack/minimum_string_length_after_removing_substrings/__init__.py new file mode 100644 index 00000000..d4c517c5 --- /dev/null +++ b/algorithms/stack/minimum_string_length_after_removing_substrings/__init__.py @@ -0,0 +1,55 @@ +from typing import List + + +def min_length_stack(s: str) -> int: + stack: List[str] = [] + + for char in s: + # If the stack is empty + if len(stack) == 0: + # Add the current character to the stack and continue to the next character + stack.append(char) + continue + # If the current character is B and the top of the stack is A + if char == "B" and stack[-1] == "A": + # Pop off the character from the stack + stack.pop() + # If the current character is D and the top of the stack is C + elif char == "D" and stack[-1] == "C": + # Pop off the character from the top of the stack + stack.pop() + else: + # otherwise, push the current character to the stack + stack.append(char) + return len(stack) + + +def min_length_string_replace(s: str) -> int: + while "AB" in s or "CD" in s: + if "AB" in s: + s = s.replace("AB", "") + elif "CD" in s: + s = s.replace("CD", "") + + return len(s) + + +def min_length_in_place_manipulation(s: str) -> int: + char_list = list(s) + write_ptr = 0 + + for read_ptr in range(len(s)): + # Write the current character to the current write position + char_list[write_ptr] = char_list[read_ptr] + + # Check if we have a valid pattern to remove + if ( + write_ptr > 0 + and char_list[write_ptr - 1] in "AC" + and ord(char_list[write_ptr]) == ord(char_list[write_ptr - 1]) + 1 + ): + write_ptr -= 1 + else: + write_ptr += 1 # No match, so move the write pointer forward + + return write_ptr diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_1.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_1.png new file mode 100644 index 00000000..225eef56 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_1.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_2.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_2.png new file mode 100644 index 00000000..2af4a0e1 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_2.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_3.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_3.png new file mode 100644 index 00000000..ea2a3cf1 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/examples/minimum_string_length_after_removing_substrings_example_3.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_1.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_1.png new file mode 100644 index 00000000..de57fc81 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_1.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_2.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_2.png new file mode 100644 index 00000000..28623fe5 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_2.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_3.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_3.png new file mode 100644 index 00000000..33fbf11a Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_3.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_4.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_4.png new file mode 100644 index 00000000..d6c42aa0 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_4.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_5.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_5.png new file mode 100644 index 00000000..c022190a Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_5.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_6.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_6.png new file mode 100644 index 00000000..9662cc27 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_6.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_7.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_7.png new file mode 100644 index 00000000..f1c9790c Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_7.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_8.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_8.png new file mode 100644 index 00000000..a85a5e70 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_in-place_solution_8.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_1.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_1.png new file mode 100644 index 00000000..257e429c Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_1.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_10.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_10.png new file mode 100644 index 00000000..ddc1fb6b Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_10.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_11.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_11.png new file mode 100644 index 00000000..98509be4 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_11.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_12.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_12.png new file mode 100644 index 00000000..3313ae1d Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_12.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_2.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_2.png new file mode 100644 index 00000000..5f9c4ea5 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_2.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_3.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_3.png new file mode 100644 index 00000000..3f7ce741 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_3.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_4.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_4.png new file mode 100644 index 00000000..e7e050d9 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_4.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_5.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_5.png new file mode 100644 index 00000000..4cad0026 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_5.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_6.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_6.png new file mode 100644 index 00000000..455012c1 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_6.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_7.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_7.png new file mode 100644 index 00000000..ee7c92b5 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_7.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_8.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_8.png new file mode 100644 index 00000000..c2857e94 Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_8.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_9.png b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_9.png new file mode 100644 index 00000000..0616a2cd Binary files /dev/null and b/algorithms/stack/minimum_string_length_after_removing_substrings/images/solutions/minimum_string_length_after_removing_substrings_stack_solution_9.png differ diff --git a/algorithms/stack/minimum_string_length_after_removing_substrings/test_min_str_length_after_removing_substrings.py b/algorithms/stack/minimum_string_length_after_removing_substrings/test_min_str_length_after_removing_substrings.py new file mode 100644 index 00000000..0cf3112d --- /dev/null +++ b/algorithms/stack/minimum_string_length_after_removing_substrings/test_min_str_length_after_removing_substrings.py @@ -0,0 +1,38 @@ +import unittest +from parameterized import parameterized +from algorithms.stack.minimum_string_length_after_removing_substrings import ( + min_length_stack, + min_length_string_replace, + min_length_in_place_manipulation, +) + +MIN_STR_LENGTH_AFTER_REMOVING_SUBSTRINGS_TEST_CASES = [ + ("ABCD", 0), + ("ACDBD", 1), + ("ACBD", 4), + ("ABCDXYZCDAB", 3), + ("A", 1), + ("ABFCACDB", 2), + ("ACBBD", 5), +] + + +class MinStrLengthAfterRemovingSubstringsTestCase(unittest.TestCase): + @parameterized.expand(MIN_STR_LENGTH_AFTER_REMOVING_SUBSTRINGS_TEST_CASES) + def test_min_length(self, s: str, expected: int): + actual = min_length_stack(s) + self.assertEqual(expected, actual) + + @parameterized.expand(MIN_STR_LENGTH_AFTER_REMOVING_SUBSTRINGS_TEST_CASES) + def test_min_length_string_replace(self, s: str, expected: int): + actual = min_length_string_replace(s) + self.assertEqual(expected, actual) + + @parameterized.expand(MIN_STR_LENGTH_AFTER_REMOVING_SUBSTRINGS_TEST_CASES) + def test_min_length_in_place_manipulation(self, s: str, expected: int): + actual = min_length_in_place_manipulation(s) + self.assertEqual(expected, actual) + + +if __name__ == "__main__": + unittest.main()