I am working on a coding problem in which I have to delete all occurrences of a substring T in a string S (keeping in mind that removing one occurrence of T in S may generate a new occurrence of T), and then to return the resulting string S after all deletions. The size of both S and T can be up to 10^6.
For example, if I have S = "aabcbcd" and T = "abc", then removing all occurrences of abc in S results in S = "d".
The sample solution to this problem involves building a string R from S one character at a time, and whenever the end of R matches T, we delete it from R (the comparison between the end of R and T is determined by string hashing).
The solution says that
Since this deletion is at the end of R this is just a simple O(1) resize operation.
However, according to https://m.cplusplus.com/reference/string/string/resize/ the time complexity of string::resize is linear in the new string length. Ben Voigt confirms this in Why is string::resize linear in complexity?.
Also, in the solution the code involves using string::substr to double check if the end of R and T match (since hash(the end of R)==hash(T) does not guarantee the end of R equals to T):
/* If the end of R and T match truncate the end of R (and associated hash arrays). */
if (hsh == thsh && R.substr(R.size() - T.size()) == T) {
//...
}
Once again, https://m.cplusplus.com/reference/string/string/substr/ says that string::substr has linear time complexity.
Even if string::substr wasn't linear, then comparing the two strings directly would still cause the comparison to be linear in the size of T.
If this is true, wouldn't the time complexity of the solution be at least O(S.length()*T.length()), instead of O(S.length()) (according to the solution)? Any help is appreciated!