June 16th 2023
Problem Description permalink
You are given a string s, which contains stars *.
In one operation, you can:
Choose a star in s. Remove the closest non-star character to its left, as well as remove the star itself. Return the string after all stars have been removed.
Note:
The input will be generated such that the operation is always possible. It can be shown that the resulting string will always be unique.
Example 1:
Input: s = "leet**cod*e"
Output: "lecoe"
Explanation: Performing the removals from left to right:
- The closest character to the 1st star is 't' in "leet**cod*e". s becomes "lee*cod*e".
- The closest character to the 2nd star is 'e' in "lee*cod*e". s becomes "lecod*e".
- The closest character to the 3rd star is 'd' in "lecod*e". s becomes "lecoe".
There are no more stars, so we return "lecoe".
Solution 1 permalink
// Return the position of the closest start
// Returns -1 if no stars are left in the string
function closestStar(s: string): number {
return s.indexOf("*")
}
type StarRemovalOperation = {
// The string after the star and the character immediately to the left
// have been removed
newString: string,
// The character that was immediately to the left of the star
character: string,
}
function removeStarAtPosition(s: string, position: number): StarRemovalOperation {
const char = s[position - 1]
return {
character: char,
newString: s.replace(`${char}*`, "")
}
}
function removeStars(s: string): string {
let inputString = s;
let posOfClosestStar = closestStar(inputString)
while (posOfClosestStar != -1) {
const removed = removeStarAtPosition(inputString, posOfClosestStar)
inputString = removed.newString
posOfClosestStar = closestStar(inputString)
}
return inputString
};
Discussion 1 permalink
This solution closely follows the algorithm laid out in the problem description. If I was on a team and a product person had outlined the algorithm this is what I would want to ship. I like it because it's debuggable and it follows the mental model.
But it's also slow
Solution 2 permalink
function removeStars(s: string): string {
var result = s;
while (result.includes("*")) {
result = result.replace(new RegExp("[a-z][*]", "g"), "")
}
return result
};
Discussion 2 permalink
This is faster and it still mostly follows the mental model. But it's also still not fast enough.
Solution 3 permalink
function removeStars(s: string): string {
var result: string[] = []
for (var char of s.split("")) {
if (char == "*") {
result.pop()
} else {
result.push(char)
}
}
return result.join("")
};
Discussion 3 permalink
This treat the input as a command string and the result as a stack to push and pop from. It's slightly different than the way the algorithm was outlined. If this was a bit of code that was in a critical path (like in the middle of an HTTP request) or was run on large data this would be the one I shipped.