ctci/1. Arrays and strings/1.3. replace_char.md

2.5 KiB

1.3. URLify

Replace all spaces in a string with '%20'. The string has sufficient space at the end to hold the additional characters, and as input we receive the true length of the string

example:

  • input: 'Mr John Smith ', 13
  • output: 'Mr%20John%20Smith'

First, understand the input

true length 13? so we're supposed to stop if we reach string length 13, even if the input string is longer? I assume this is the case.

Initial idea

BCR is O(n), we have to go through the string at least once.

def replace_char(s, maxlen):
    news = ''
    for i in range(maxlen):
        if s[i] == ' ':
            news += '%20'
        else:
            news += s[i]
    return news

This runs in O(n) time and O(n) space. Can we do O(1) space? Replace in string directly?

maxlen must be smaller than len? If it's bigger, this won't work

maxlen = min(maxlen, len(s))

At most, it'll be as long as s. What if it's negative?

maxlen = max(0, maxlen)

tests

  • '', 3 -> ''
  • 'ane ', 3 -> 'ane'
  • 'ane ', 4 -> 'ane%20'
  • 'a ne', 5 -> 'a%20ne'

Improved idea

def replace_char(s, maxlen):
    maxlen = max(0, maxlen)
    maxlen = min(maxlen, len(s))
    for i in range(maxlen):
        if s[i] == ' ':
            s[i] = '%20' # fails
    return s

don't know if this works in python... but it'd be O(1). Doesnt work in python, strings are inmutable. Either use lists, or:

new = text[:1] + 'Z' + text[2:]

which creates another string, so O(n) anyway.

REMEMBER: there's no append in strings in python, s += 'a'

Tests OK.

Another language

Strings are mutable in C++:

int main() {
    std::string s = "abc";
    s[1] = 'a';
}

or use string.replace(). This'd take O(1) in space.

Solution

A common approach is to edit the string starting from the end and working backwards, because we have an extra buffer at the end, which allows us to change characters without worrying about overwriting.

First count number of spaces (? why?). We need two extra characters for each space because %20 is two characters longer than ' ', so we multiply # of spaces * 2. Then we walk backwards through the string, editing it. When we see a space, replace it with %20. Else, copy original character.

The solution is implemented in Java character arrays (char[] str), where strings are inmutable.

Conclusion

Careful which language I use, strings might be mutable or not. Best case scenario, C++, O(n) time and O(1) space.