Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have been working my way through the exercises in the book Cracking the Coding Interview. I wanted to get feedback for the following exercise.

Write a method to replace all spaces in a string with '%20'. You may assume that the string has sufficient space at the end to hold the additional characters and that you are given the true length of the string.

Example:

Input: "Mr_John_Smith____ ", 13
Output: "Mr%20John%20Smith"

Note: I am using '_' to represent spaces above because I could not get spaces to format nicely.

I would be interested in feedback on my code and time/space complexity computation below, and would also be interested to know if there is any way to improve the time or space complexity of my code.

def urlify(in_string, in_string_length):
    in_string = list(in_string)
    for position, character in reversed(list(enumerate(in_string[0:in_string_length]))):
        if character == ' ':
            in_string[position + 3:in_string_length + 2] = in_string[position + 1:in_string_length]
            in_string[position:position + 3] = '%20'
            in_string_length += 2
    return ''.join(in_string)

My guess is that the time complexity of the code above is \$O(1(n - s) +sn)\$ where \$n\$ is the length of the input string, \$ s\$ is the number of spaces in the input string (not including trailing spaces).

My reasoning is that if there are 0 spaces then the for loop will only do constant work checking the if statement and then perform the join at the end which all together is \$O(n)\$ whereas in the other extreme case where there are \$n\$ spaces, the work done will be \$O(n^{2})\$. Lastly I think the space complexity is \$O(n).\$

share|improve this question
    
Follow-up question – 200_success Sep 15 at 1:40
up vote 4 down vote accepted

Your complexity analyses look correct to me. I would just say, in short, that this function works in O(n2) time.

Note that this is an awkward exercise to do in Python, or any language in which strings are immutable. Since you can't perform the substitutions in place, you have to return a copy, which means that the minimum space requirement is O(n). In that case, you might as well do either:

def urlify(in_string, in_string_length):
    return in_string[:in_string_length].replace(' ', '%20')

… or:

def urlify(in_string, in_string_length):
    return ''.join('%20' if c == ' ' else c for c in in_string[:in_string_length])

… which should also be O(n) space, O(n) time, and much simpler to implement!

That said, if we were to reinterpret the exercise to work on a buffer in place, I think that a better approach would be to make one pass to count the spaces in the input, to figure out the length of the output. Then, copy characters to construct the result, working backwards from the end. That algorithm should take O(n) time and O(1) space.

In summary, depending on how you interpret the exercise, the solution should either be simpler or faster than what you wrote.

share|improve this answer
    
Two Questions 1) I used a character array by doing list(in_string), and then iterated over the string working backwards as you stated. Is it because i did this shifting in place that i ended up with poor performance? Is it because i did not pre-compute the number of spaces in the string? 2) Are you saying that since i had to convert from a string to a character array i can not do better than O(n) space and so i should have favored a simpler (python) implementation that can give me O(n) time rather than implementing the working backwards from the end approach? – newToProgramming Sep 14 at 1:54
1  
1) Yes, that's right. If you know the length of the output, then you can do all of the copying in just one pass. 2) Yes, that is what I'm saying. – 200_success Sep 14 at 1:56
1  
Spoiler: the same exercise, done in C and in Java. – 200_success Sep 14 at 2:02
1  
1  
@new You can always ask a followup question, link to the original question, and mention what you fixed and what you would like another review to focus on. – Graipher Sep 14 at 7:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.