A valid IP address consists of exactly four integers separated by single dots. Each integer is between 0
and 255
(inclusive) and cannot have leading zeros.
"0.1.2.201"
and "192.168.1.1"
are valid IP addresses, but "0.011.255.245"
, "192.168.1.312"
and "192.168@1.1"
are invalid IP addresses.Given a string s
containing only digits, return all possible valid IP addresses that can be formed by inserting dots into s
. You are not allowed to reorder or remove any digits in s
. You may return the valid IP addresses in any order.
Example 1:
Input: s = "25525511135"
Output: ["255.255.11.135","255.255.111.35"]
Example 2:
Input: s = "0000"
Output: ["0.0.0.0"]
Example 3:
Input: s = "101023"
Output: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
Constraints:
1 <= s.length <= 20
s
consists of digits only.def restoreIpAddresses(s):
def isValid(segment):
# Check if the segment is between 0 and 255
# and doesn't have leading zeros (unless it's just "0")
return 0 <= int(segment) <= 255 and (segment == "0" or not segment.startswith("0"))
def backtrack(start, dots, currentIP):
if dots == 4:
if start == len(s):
result.append(currentIP[:-1]) # Remove the trailing dot
return
for i in range(start, min(start + 3, len(s))):
segment = s[start:i + 1]
if isValid(segment):
backtrack(i + 1, dots + 1, currentIP + segment + ".")
result = []
backtrack(0, 0, "")
return result
# Example usage:
s = "25525511135"
print(restoreIpAddresses(s))
s = "0000"
print(restoreIpAddresses(s))
s = "101023"
print(restoreIpAddresses(s))
# Edge Cases
s = ""
print(restoreIpAddresses(s))
s = "11111111111111111111111111111"
print(restoreIpAddresses(s))
s = "010010"
print(restoreIpAddresses(s))
This code implements a backtracking algorithm to find all possible valid IP addresses that can be formed from a given string s
. Here's a breakdown of how it works:
restoreIpAddresses(s)
Function:
s
and returns a list of valid IP addresses.result
to store the valid IP addresses.backtrack
helper function to generate IP addresses recursively.result
list.isValid(segment)
Function:
True
if the segment meets the following conditions:
backtrack(start, dots, currentIP)
Function:
start
: The starting index of the remaining part of the string s
to process.dots
: The number of dots already placed in the currentIP
.currentIP
: The current IP address being built.dots
is 4, it means we have placed 3 dots and formed 4 segments. If start
is also equal to the length of s
, it means we have used all the digits in s
and formed a valid IP address. In this case, we add the currentIP
(without the trailing dot) to the result
list.start
index.isValid
function.backtrack
with the updated start
index, dots
count, and the currentIP
with the new segment added.A naive solution would involve generating all possible combinations of inserting three dots into the string s
and then checking if each combination forms a valid IP address. This would involve a lot of redundant calculations and checks, making it inefficient.
The provided code represents the optimal solution, which uses backtracking to efficiently explore the possible IP address combinations while pruning invalid branches early on. Backtracking is a general algorithm for finding all (or some) solutions to some computational problems, notably constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons a candidate ("backtracks") as soon as it determines that the candidate cannot possibly be completed to a valid solution.
The time complexity is difficult to precisely determine due to the constraints imposed by IP address validity. However, we can analyze the factors influencing it:
In the worst-case scenario (e.g., "111111111111"), the algorithm explores numerous paths but is bounded by the IP address structure. A loose upper bound is O(3^4) = O(81), but since not all paths are valid, this is an overestimate. A more accurate consideration gives a time complexity closer to O(1), but in reality, it depends on the input string. Thus, O(1) describes it best, considering practical input constraints.
The recursion depth is limited to 4, so the recursion stack takes O(1) space. The number of valid IP addresses can vary but is limited by the input string length. Thus, in the worst case, the space complexity to store all the results is O(1), considering that the number of valid IP addresses is limited by the length of the input string and is not unbounded. Therefore, space complexity is O(1).