Skip to content

Commit bd9fbd8

Browse files
committed
Problem: Comparing Strings Containing Backspaces
1 parent f21f658 commit bd9fbd8

File tree

6 files changed

+574
-53
lines changed

6 files changed

+574
-53
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Problem: Comparing Strings Containing Backspaces
2+
3+
LeetCode problem: [844. Backspace String Compare](https://leetcode.com/problems/backspace-string-compare/).
4+
5+
Given two strings containing backspaces (identified by the character `#`), check if the two strings are equal.
6+
7+
## Examples
8+
9+
Example 1:
10+
11+
```plaintext
12+
Input: str1 = "xy#z", str2 = "xzz#"
13+
Output: true
14+
Explanation: After applying backspaces the strings become "xz" and "xz" respectively.
15+
```
16+
17+
Example 2:
18+
19+
```plaintext
20+
Input: str1 = "xy#z", str2 = "xyz#"
21+
Output: false
22+
Explanation: After applying backspaces the strings become "xz" and "xy" respectively.
23+
```
24+
25+
Example 3:
26+
27+
```plaintext
28+
Input: str1 = "xp#", str2 = "xyz##"
29+
Output: true
30+
Explanation: After applying backspaces the strings become "x" and "x" respectively.
31+
In "xyz##", the first '#' removes the character 'z' and the second '#' removes the character 'y'.
32+
```
33+
34+
Example 4:
35+
36+
```plaintext
37+
Input: str1 = "xywrrmp", str2 = "xywrrmu#p"
38+
Output: true
39+
Explanation: After applying backspaces the strings become "xywrrmp" and "xywrrmp" respectively.
40+
```
41+
42+
## Solution 1
43+
44+
The algorithm builds both strings by skipping characters affected by backspaces (`#`). It then compares the two final strings, returning true if they are identical, or false if they differ.
45+
46+
Complexity analysis:
47+
48+
- Time complexity: O(N+M)
49+
- Space complexity: O(N+M)
50+
51+
Where `N` and `M` are the lengths of the two input strings respectively.
52+
53+
```python
54+
# O(K) time and O(K) space
55+
# where K is the length of the string parameter
56+
def removeBackspaces(string: str) -> str:
57+
string_new = ""
58+
string_backspaces = 0
59+
60+
current = len(string) - 1
61+
while current >= 0:
62+
if string[current] == "#":
63+
string_backspaces += 1
64+
elif string_backspaces > 0:
65+
string_backspaces -= 1
66+
else:
67+
string_new += string[current]
68+
69+
current -= 1
70+
71+
return string_new[::-1]
72+
73+
def backspaceCompare(s: str, t: str) -> bool:
74+
s_new = removeBackspaces(s)
75+
t_new = removeBackspaces(t)
76+
77+
return s_new == t_new
78+
```
79+
80+
## Solution 2
81+
82+
The algorithm uses two pointers to traverse the strings from the end to the beginning, skipping characters that are deleted by backspaces (`#`).
83+
84+
To handle the backspaces, it finds the next valid character in each string by counting the backspaces (`#`) and skipping over the characters that would be deleted. Once both pointers are positioned at valid characters, those characters are compared. If they match, the pointers move to the previous valid characters and repeat the process, otherwise it returns false.
85+
86+
If at any point, one string still has valid characters remaining while the other does not, it returns false.
87+
88+
Complexity analysis:
89+
90+
- Time complexity: O(N+M)
91+
- Space complexity: O(1)
92+
93+
Where `N` and `M` are the lengths of the two input strings respectively.
94+
95+
```python
96+
# O(K) time and O(1) space
97+
# where K is the length of the string parameter
98+
def getNextValidIndex(string: str, index: int) -> int:
99+
backspaces = 0
100+
while index >= 0:
101+
if string[index] == "#":
102+
backspaces += 1
103+
elif backspaces > 0:
104+
backspaces -= 1 # found a character that is affected by a backspace, skip it
105+
else:
106+
break # found a valid character that is not affected by any backspace
107+
index -= 1
108+
109+
return index
110+
111+
def backspaceCompare(s: str, t: str) -> bool:
112+
current_s = len(s) - 1
113+
current_t = len(t) - 1
114+
while current_s >= 0 or current_t >= 0:
115+
current_s = getNextValidIndex(s, current_s)
116+
current_t = getNextValidIndex(t, current_t)
117+
118+
# if both pointers have valid characters, compare them
119+
if current_s >= 0 and current_t >= 0 and s[current_s] != t[current_t]:
120+
return False
121+
122+
# if one string has a valid character left and the other doesn't,
123+
if (current_s >= 0 and current_t < 0) or (current_t >= 0 and current_s < 0):
124+
return False
125+
126+
current_s -= 1
127+
current_t -= 1
128+
129+
return True
130+
```
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Problem: Minimum Window Sort
2+
3+
LeetCode problem: [581. Shortest Unsorted Continuous Subarray](https://leetcode.com/problems/shortest-unsorted-continuous-subarray/).
4+
5+
Given an array, find the length of the smallest subarray in it which when sorted will sort the whole array.
6+
7+
## Examples
8+
9+
Example 1:
10+
11+
```plaintext
12+
Input: [1, 2, 5, 3, 7, 10, 9, 12]
13+
Output: 5
14+
Explanation: We need to sort only the subarray [5, 3, 7, 10, 9] to make the whole array sorted
15+
```
16+
17+
Example 2:
18+
19+
```plaintext
20+
Input: [1, 3, 2, 0, -1, 7, 10]
21+
Output: 5
22+
Explanation: We need to sort only the subarray [1, 3, 2, 0, -1] to make the whole array sorted
23+
```
24+
25+
Example 3:
26+
27+
```plaintext
28+
Input: [1, 2, 3]
29+
Output: 0
30+
Explanation: The array is already sorted
31+
```
32+
33+
Example 4:
34+
35+
```plaintext
36+
Input: [3, 2, 1]
37+
Output: 3
38+
Explanation: The whole array needs to be sorted.
39+
```
40+
41+
## Solution 1
42+
43+
The algorithm first creates a sorted copy of the input array. It then iterates through both the input and sorted arrays to identify the start and end indices of the unsorted subarray.
44+
45+
By comparing corresponding elements in the input array and the sorted array, it finds the first and last positions where the elements differ.
46+
47+
Complexity analysis:
48+
49+
- Time complexity: O(N * LogN)
50+
- Space complexity: O(N)
51+
52+
```python
53+
def findUnsortedSubarray(nums: List[int]) -> int:
54+
sorted_nums = list(sorted(nums))
55+
56+
start = None
57+
end = None
58+
for i in range(len(nums)):
59+
if nums[i] != sorted_nums[i]:
60+
if start is None:
61+
start = i
62+
end = i
63+
else:
64+
end = i
65+
66+
return (end - start) + 1 if start is not None else 0
67+
```
68+
69+
## Solution 2
70+
71+
The algorithm starts by identifying both the start and the end of the candidate unsorted subarray through the following steps:
72+
73+
1. It begins from the start of the array to find the first element that is out of order (i.e., an element smaller than its previous element).
74+
2. Similarly, it starts from the end of the array to find the first element that is out of order (i.e., an element larger than its previous element).
75+
76+
But sorting this subarray may not necessarily result in the entire array being sorted. Here is an example:
77+
78+
```plaintext
79+
Input: [1, 3, 2, 0, -1, 7, 10]
80+
Sorting the numbers between '3' and '-1' will not sort the whole array: [1, -1, 0, 2, 3, 7, 10]
81+
```
82+
83+
This happens when any of the following two conditions is met:
84+
85+
1. There is a number before the candidate unsorted subarray that is larger than any number in the unsorted subarray.
86+
2. There is a number after the candidate unsorted subarray that is smaller than any number in the unsorted subarray.
87+
88+
To sort the entire array, it is necessary to include all such elements that are larger than the smallest element of the unsorted subarray and all elements that are smaller than the largest element of the unsorted subarray.
89+
90+
Therefore, the final algorithm proceeds as follows:
91+
92+
1. From the beginning of the array, find the first element that is out of order. This element marks the start of the candidate unsorted subarray.
93+
2. From the end of the array, find the first element that is out of order. This element marks the end of the candidate unsorted subarray.
94+
3. Find the minimum and maximum values within this unsorted subarray.
95+
4. Extend the subarray to the left to include any elements that are larger than the minimum value of the unsorted subarray.
96+
5. Similarly, extend the subarray to the right to include any elements that are smaller than the maximum value of the unsorted subarray.
97+
98+
Complexity analysis:
99+
100+
- Time complexity: O(N)
101+
- Space complexity: O(1)
102+
103+
```python
104+
# O(N) time and O(1) space
105+
def findUnsortedSubarrayIndices(nums: List[int]) -> Tuple[Optional[int], Optional[int]]:
106+
left = 0
107+
while left < len(nums) - 1 and nums[left] <= nums[left + 1]:
108+
left += 1
109+
110+
# if the array is sorted
111+
if left == len(nums) - 1:
112+
return None, None
113+
114+
right = len(nums) - 1
115+
while right > 0 and nums[right] >= nums[right - 1]:
116+
right -= 1
117+
118+
return left, right
119+
120+
# O(N) time and O(1) space
121+
def findSubarrayMinimumAndMaximum(nums: List[int], start: int, end: int) -> Tuple[int, int]:
122+
minimum = float("inf")
123+
maximum = float("-inf")
124+
for i in range(start, end + 1):
125+
minimum = min(minimum, nums[i])
126+
maximum = max(maximum, nums[i])
127+
128+
return minimum, maximum
129+
130+
def findUnsortedSubarray(nums: List[int]) -> int:
131+
start, end = findUnsortedSubarrayIndices(nums)
132+
133+
# if the array is sorted
134+
if start is None and end is None:
135+
return 0
136+
137+
# find minimum and maximum numbers in the unsorted subarray
138+
minimum, maximum = findSubarrayMinimumAndMaximum(nums, start, end)
139+
140+
# expand the subarray to the left to include any element before the subarray
141+
# which is smaller than the minimum element of the unsorted subarray
142+
temp = start - 1
143+
while temp >= 0:
144+
if nums[temp] > minimum:
145+
start = temp
146+
temp -= 1
147+
148+
# expand the subarray to the right to include any element after the subarray
149+
# which is larger than the maximum element of the unsorted subarray
150+
temp = end + 1
151+
while temp <= len(nums) - 1:
152+
if nums[temp] < maximum:
153+
end = temp
154+
temp += 1
155+
156+
return (end - start) + 1
157+
```

01-two-pointers/README.md

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
11
# Pattern: Two Pointers
22

3-
The two pointers technique uses two pointers (or indices) to traverse the sequence (such as an array, string, or linked list) simultaneously in order to get the answer faster.
4-
5-
Forms:
6-
7-
1. Two pointers either move towards each other or move in the same direction.
8-
2. Two pointers moving in different pace, starting from the same position or different positions.
9-
10-
---
11-
12-
This folder contains code for the classic form of the two pointers technique, where **the pointers either start from opposite ends of a sequence and move towards each other or begin at the same point and move together.**.
3+
The two pointers technique uses two pointers (or indices) to simultaneously traverse the sequence (such as an array, string, or linked list) either by moving toward each other or in a particular direction until they meet.
134

145
This technique is often used in problems that require finding pairs or sub-arrays that satisfy certain conditions (e.g., sum of two elements, checking for a palindrome).
156

16-
---
17-
187
## Problems
198

20-
| Problem | Complexity |
21-
| :----------------------------------------------------------------: | :---------------------: |
22-
| [Pair with Target Sum](./01-pair-with-target-sum.md) | :star2: |
23-
| [Remove Duplicates](./02-remove-duplicates.md) | :star2: |
24-
| [Squaring a Sorted Array](./03-squaring-a-sorted-array.md) | :star2: |
25-
| [Triplet Sum to Zero](./04-triplet-sum-to-zero.md) | :star2: :star2: |
26-
| [Triplet Sum Close to Target](./05-triplet-sum-close-to-target.md) | :star2: :star2: |
27-
| [Triplets with Smaller Sum](./06-triplets-with-smaller-sum.md) | :star2: :star2: |
28-
| [Dutch National Flag Problem](./07-dutch-national-flag-problem.md) | :star2: :star2: |
29-
| [Quadruple Sum to Target](./08-quadruple-sum-to-target.md) | :star2: :star2: |
9+
| Problem | Complexity |
10+
| :--------------------------------------------------------------------------------------------: | :-------------: |
11+
| [Pair with Target Sum](./01-pair-with-target-sum.md) | :star2: |
12+
| [Remove Duplicates](./02-remove-duplicates.md) | :star2: |
13+
| [Squaring a Sorted Array](./03-squaring-a-sorted-array.md) | :star2: |
14+
| [Triplet Sum to Zero](./04-triplet-sum-to-zero.md) | :star2: :star2: |
15+
| **[Triplet Sum Close to Target](./05-triplet-sum-close-to-target.md)** | :star2: :star2: |
16+
| [Triplets with Smaller Sum](./06-triplets-with-smaller-sum.md) | :star2: :star2: |
17+
| [Dutch National Flag Problem](./07-dutch-national-flag-problem.md) | :star2: :star2: |
18+
| [Quadruple Sum to Target](./08-quadruple-sum-to-target.md) | :star2: :star2: |
19+
| **[Comparing Strings Containing Backspaces](./09-comparing-strings-containing-backspaces.md)** | :star2: :star2: |
20+
| **[Minimum Window Sort](./10-minimum-window-sort.md)** | :star2: :star2: |

0 commit comments

Comments
 (0)