Skip to content
← All posts

Defanging an IP Address: Simple String Replacement

4 min read
leetcodeproblemeasystrings

LeetCode 1108, Defanging an IP Address, asks you to take a valid IPv4 address and return a "defanged" version where every period "." is replaced by "[.]".

For example, given address = "1.1.1.1", you return "1[.]1[.]1[.]1". Given address = "255.100.50.0", you return "255[.]100[.]50[.]0".

That is the entire problem. No validation, no parsing, no special cases. Just find every dot and wrap it in brackets.

input1.1.1.1output1[.]1[.]1[.]1
Each dot in the original IP address is replaced by "[.]" to produce the defanged version.

The approach

You have two clean options here, and both work perfectly well.

Option 1: Built-in replace. Python's str.replace method does exactly what the problem asks. Call address.replace(".", "[.]") and you are done. The method scans the string from left to right, finds every occurrence of the target substring, and substitutes it with the replacement. One line, no edge cases to worry about.

Option 2: Manual iteration. Walk through each character in the string. If it is a dot, append "[.]" to a result list. Otherwise, append the character as-is. Join the list at the end. This approach is more verbose, but it shows the replacement logic explicitly, which is useful when you need to convince yourself (or an interviewer) that you understand what is happening under the hood.

Both approaches produce identical output. The built-in method is what you would use in production code. The manual version is what demonstrates understanding in an interview.

Python solution

The one-liner using built-in replace:

def defangIPaddr(address):
    return address.replace(".", "[.]")

And the manual iteration approach:

def defangIPaddr(address):
    result = []
    for char in address:
        if char == ".":
            result.append("[.]")
        else:
            result.append(char)
    return "".join(result)

Both do the same thing. The first lets Python handle the traversal internally. The second makes every step explicit.

Step-by-step walkthrough

Here is what happens when you process "1.1.1.1" character by character using the manual approach.

Character 0: '1'

input1.1.1.1result1

Not a dot. Append '1' directly to the result.

Character 1: '.'

input1.1.1.1result1[.]

It is a dot. Append "[.]" instead of "." to defang it.

Character 2: '1'

input1.1.1.1result1[.]1

Not a dot. Append '1' directly.

Character 3: '.'

input1.1.1.1result1[.]1[.]

Dot found. Append "[.]".

Character 4: '1'

input1.1.1.1result1[.]1[.]1

Not a dot. Append '1'.

Character 5: '.'

input1.1.1.1result1[.]1[.]1[.]

Dot found. Append "[.]".

Character 6: '1'

input1.1.1.1result1[.]1[.]1[.]1

Not a dot. Append '1'. We have reached the end of the input.

Seven characters in the input, seven iterations. Each dot becomes three characters ([.]) in the output, so the final string is 13 characters long.

Complexity

Complexity
TimeO(n)
SpaceO(n)

You visit every character exactly once, so the time is O(n) where n is the length of the input string. The output string can be at most roughly 3x the input length (if every character were a dot), but that is still O(n). The space for the result string is O(n) as well.

Building blocks

This problem is about as minimal as string manipulation gets, but the underlying pattern shows up everywhere:

  • Character-level scanning. Many string problems ask you to walk through each character, decide what to do, and build a new string. Defanging an IP Address is the simplest version of this pattern.
  • Conditional replacement. The "if this character, substitute that" logic is the same skeleton used in problems like encoding, decoding, escaping special characters, and run-length encoding.
  • Builder pattern. Appending to a list and joining at the end (rather than concatenating strings in a loop) is the standard Python idiom for building strings efficiently. You will reuse this in almost every string-building problem.

Even though this is an easy problem, practicing it helps you internalize the scan-and-build loop so that it becomes automatic when you face harder variations.

Edge cases

Minimum length. The shortest valid IPv4 address is something like "0.0.0.0", which is 7 characters. There are always exactly 3 dots, so the output always grows by exactly 6 characters (each dot becomes 3 characters, a net gain of 2 per dot).

Large octets. An address like "255.255.255.255" has 15 characters. The output is "255[.]255[.]255[.]255", which is 21 characters. The replacement logic does not change regardless of the number of digits in each octet.

No dots to worry about missing. The problem guarantees a valid IPv4 address, so there are always exactly 3 dots. You never need to handle the case of zero dots or more than three.

From understanding to recall

This problem feels trivially easy when you read the solution. You might think there is nothing to memorize. But the real value is in the pattern, not the problem. The scan-and-build loop, the conditional append, the final join -- these are building blocks that appear in dozens of harder problems.

Spaced repetition helps you cement these micro-patterns so that when you face a harder string problem, you do not waste time reinventing the basic loop structure. You just reach for it automatically and spend your mental energy on the harder parts of the problem.

Related posts

  • Reverse String -- another fundamental string manipulation problem that builds muscle memory for in-place operations
  • String Compression -- uses the same scan-and-build pattern with a counting twist
  • Validate IP Address -- the parsing side of IP addresses, where you split on dots instead of replacing them