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.You are 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 = "101023"
Output: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]Example 2:
Input: s = "010010"
Output: ["0.10.0.10","0.100.1.0"]Constraints:
1 <= s.length <= 20s consists of digits only.Before attempting this problem, you should be comfortable with:
A valid IP address has exactly four segments, each containing 1 to 3 digits with a value between 0 and 255. Leading zeros are not allowed except for the segment "0" itself. Backtracking lets us explore all possible ways to place three dots in the string. At each step, we try taking 1, 2, or 3 characters for the current segment, validate it, and recurse for the remaining segments.
i, number of segments placed dots, and the IP being built curIP.class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
res = []
if len(s) > 12:
return res
def backtrack(i, dots, curIP):
if dots == 4 and i == len(s):
res.append(curIP[:-1])
return
if dots > 4:
return
for j in range(i, min(i + 3, len(s))):
if i != j and s[i] == "0":
continue
if int(s[i: j + 1]) < 256:
backtrack(j + 1, dots + 1, curIP + s[i: j + 1] + ".")
backtrack(0, 0, "")
return resWhere is equals to as there are at most three digits in a valid segment and is equals to as there are four segments in a valid IP.
Since there are exactly four segments and each can have 1, 2, or 3 characters, we can enumerate all 81 combinations (3^4) of segment lengths directly. For each combination, we check if the total length matches the input string and whether each resulting segment is valid. This avoids recursion overhead while still exploring all possibilities.
seg1, seg2, seg3, seg4).res.class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
res = []
if len(s) > 12:
return res
def valid(num):
return len(num) == 1 or (int(num) < 256 and num[0] != "0")
def add(s1, s2, s3, s4):
if s1 + s2 + s3 + s4 != len(s):
return
num1 = s[:s1]
num2 = s[s1:s1+s2]
num3 = s[s1+s2:s1+s2+s3]
num4 = s[s1+s2+s3:]
if valid(num1) and valid(num2) and valid(num3) and valid(num4):
res.append(num1 + "." + num2 + "." + num3 + "." + num4)
for seg1 in range(1, 4):
for seg2 in range(1, 4):
for seg3 in range(1, 4):
for seg4 in range(1, 4):
add(seg1, seg2, seg3, seg4)
return resWhere is equals to as there are at most three digits in a valid segment and is equals to as there are four segments in a valid IP.
Segments like "01" or "001" are invalid in IP addresses, but "0" alone is valid. The validation must specifically reject multi-digit segments that start with zero while accepting single-digit zeros.
Each segment must be at most 255. Forgetting to check this constraint or using < 256 instead of <= 255 can lead to subtle bugs, especially for three-digit segments like "256" which appear valid at first glance.
An IP address can have at most 12 digits (four segments of 3 digits each) and at least 4 digits (four segments of 1 digit each). Failing to check these bounds upfront leads to unnecessary computation on inputs that cannot possibly form valid IPs.