Welcome to Subscribe On Youtube
1910. Remove All Occurrences of a Substring
Description
Given two strings s and part, perform the following operation on s until all occurrences of the substring part are removed:
- Find the leftmost occurrence of the substring
partand remove it froms.
Return s after removing all occurrences of part.
A substring is a contiguous sequence of characters in a string.
Example 1:
Input: s = "daabcbaabcbc", part = "abc" Output: "dab" Explanation: The following operations are done: - s = "daabcbaabcbc", remove "abc" starting at index 2, so s = "dabaabcbc". - s = "dabaabcbc", remove "abc" starting at index 4, so s = "dababc". - s = "dababc", remove "abc" starting at index 3, so s = "dab". Now s has no occurrences of "abc".
Example 2:
Input: s = "axxxxyyyyb", part = "xy" Output: "ab" Explanation: The following operations are done: - s = "axxxxyyyyb", remove "xy" starting at index 4 so s = "axxxyyyb". - s = "axxxyyyb", remove "xy" starting at index 3 so s = "axxyyb". - s = "axxyyb", remove "xy" starting at index 2 so s = "axyb". - s = "axyb", remove "xy" starting at index 1 so s = "ab". Now s has no occurrences of "xy".
Constraints:
1 <= s.length <= 10001 <= part.length <= 1000s andpartconsists of lowercase English letters.
Solutions
Solution 2: Stack
Thinking
Solution 1 rescans the whole string after every deletion. Each deletion shortens $s$ by at least one character, so there can be $O(n)$ rounds and the total time is $O(n^2)$.
While reading left to right, any remaining occurrence of $\textit{part}$ that is leftmost must end at the character just read. An earlier match would already have been removed.
Keep the surviving characters on a stack. After each push, pop the last $m$ characters when they equal $\textit{part}$. One pass performs every leftmost deletion.
| Scan $s$ from left to right and store the characters that have not been removed in a string $st$. Append the current character. If $st$ has length at least $m = | \textit{part} | $ and its last $m$ characters are $\textit{part}$, delete those $m$ characters. After the scan, $st$ is the answer. |
This matches Solution 1. At every moment $st$ contains no occurrence of $\textit{part}$, so the next match must end at the character just appended, which is the leftmost occurrence in what remains.
The time complexity is $O(n \times m)$ and the space complexity is $O(n)$, where $n$ and $m$ are the lengths of $s$ and $\textit{part}$.
-
class Solution { public String removeOccurrences(String s, String part) { while (s.contains(part)) { s = s.replaceFirst(part, ""); } return s; } } // Solution 2 class Solution { public String removeOccurrences(String s, String part) { int m = part.length(); StringBuilder st = new StringBuilder(); for (int i = 0; i < s.length(); ++i) { st.append(s.charAt(i)); if (st.length() >= m && st.substring(st.length() - m).equals(part)) { st.setLength(st.length() - m); } } return st.toString(); } } -
class Solution { public: string removeOccurrences(string s, string part) { int m = part.size(); while (s.find(part) != -1) { s = s.erase(s.find(part), m); } return s; } }; // Solution 2 class Solution { public: string removeOccurrences(string s, string part) { int m = part.size(); string st; for (char c : s) { st.push_back(c); if ((int) st.size() >= m && st.compare(st.size() - m, m, part) == 0) { st.erase(st.size() - m); } } return st; } }; -
class Solution: def removeOccurrences(self, s: str, part: str) -> str: while part in s: s = s.replace(part, '', 1) return s # Solution 2 class Solution: def removeOccurrences(self, s: str, part: str) -> str: m = len(part) st = [] for c in s: st.append(c) if len(st) >= m and ''.join(st[-m:]) == part: del st[-m:] return ''.join(st) -
func removeOccurrences(s string, part string) string { for strings.Contains(s, part) { s = strings.Replace(s, part, "", 1) } return s } // Solution 2 func removeOccurrences(s string, part string) string { m := len(part) st := make([]byte, 0, len(s)) for i := 0; i < len(s); i++ { st = append(st, s[i]) if len(st) >= m && string(st[len(st)-m:]) == part { st = st[:len(st)-m] } } return string(st) } -
function removeOccurrences(s: string, part: string): string { while (s.includes(part)) { s = s.replace(part, ''); } return s; } // Solution 2 function removeOccurrences(s: string, part: string): string { const m = part.length; const st: string[] = []; for (const c of s) { st.push(c); if (st.length >= m && st.slice(-m).join('') === part) { st.length -= m; } } return st.join(''); }