Problem
I was given this problem in my Algorithms class today:
Given function
maxSubstring(s, t)
, wheres
is a string andt
is a substring ofs
, find the maximum number of iterations you can delete either the first or last occurrence of substringt
.
Concept
Here is a visualization of the function maxSubstring
called on s = banababbaa
and t = ba
.
b a n a b b a a
1st move: n a b a b b a or b a n a b a b a
2nd move: n a b b a a or n a b a b a n a b a b a or b a n a b a
3rd move: n a b a or n a b a n a b a or n a b a
4th move: n a n a
Thus, this operation takes four moves.
Attempt
Here is my solution to the problem. It works, but it is very slow when I use larger strings as arguments.
Attempt #1
function maxSubstring(s, t) {
if (s.includes(t)) {
var idxSubstr = s.replace(t, '');
var lastIdxSubstr = s.substr(0, s.lastIndexOf(t)) + s.substr(s.lastIndexOf(t) + t.length, s.length);
return 1 + Math.max(maxSubstring(idxSubstr, t), maxSubstring(lastIdxSubstr, t)));
}
return 0;
}
Attempt #2
function maxSubstring(s, t) {
if (s.includes(t)) {
var idx = s.indexOf(t), lastIdx = s.lastIndexOf(t);
var idxSubstr = s.substr(0, idx) + s.substr(idx + t.length, s.length);
var lastIdxSubstr = s.substr(0, lastIdx) + s.substr(lastIdx + t.length, s.length);
if (idx != lastIdx) {
return 1 + Math.max(maxSubstring(idxSubstr, t), maxSubstring(lastIdxSubstr, t));
} else {
return 1 + maxSubstring(idxSubstr, t);
}
}
return 0;
}
Reason for update: Minor change in efficiency by storing values of indexOf
and lastIndexOf
in variables.
Attempt #3
function maxSubstring(s, t) {
var idx = s.indexOf(t);
if (idx >= 0) {
var lastIdx = s.lastIndexOf(t);
var idxSubstr = s.substr(0, idx) + s.substr(idx + t.length);
if (idx != lastIdx) {
var lastIdxSubstr = s.substr(0, lastIdx) + s.substr(lastIdx + t.length);
return 1 + Math.max(maxSubstring(idxSubstr, t), maxSubstring(lastIdxSubstr, t));
} else {
return 1 + maxSubstring(idxSubstr, t);
}
}
return 0;
}
Reason for update: Reduced instances in which certain values were redefined and prevented lastIndexOf
calculation before the first index is checked.
Answer Requirements
Is there any algorithm or method I may use to optimize this code? Math.max
is the main culprit, so I would appreciate it if anyone has an idea on how to avoid using this method altogether.
In other words, maxSubstring
should only be called once inside of itself, but Math.max
requires that it be called twice (once for the first index of a substring and another time for the last index of that substring).
Lastly, do you mind telling me what the Big O Notation is for my solution and what the Big O Notation is for yours? This is not part of the original challenge, but I am curious, myself. Thanks in advance.