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.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The problem asks us to find all possible valid IP addresses that can be formed from a given string of digits. A brute force approach is like trying every single way to divide the string into four parts and then checking if each part is a valid number between 0 and 255.
Here's how the algorithm would work step-by-step:
def restore_ip_addresses(digits):
possible_ip_addresses = []
string_length = len(digits)
# Iterate through all possible first segment lengths
for first_segment_length in range(1, min(4, string_length)):
# Iterate through all possible second segment lengths
for second_segment_length in range(1, min(4, string_length - first_segment_length)):
# Iterate through all possible third segment lengths
for third_segment_length in range(1, min(4, string_length - first_segment_length - second_segment_length)):
fourth_segment_length = string_length - first_segment_length - second_segment_length - third_segment_length
# Ensure the fourth segment has a valid length
if 1 <= fourth_segment_length <= 3:
first_segment = digits[0:first_segment_length]
second_segment = digits[first_segment_length:first_segment_length + second_segment_length]
third_segment = digits[first_segment_length + second_segment_length:first_segment_length + second_segment_length + third_segment_length]
fourth_segment = digits[first_segment_length + second_segment_length + third_segment_length:]
# Validate each segment
if is_valid_segment(first_segment) and \
is_valid_segment(second_segment) and \
is_valid_segment(third_segment) and \
is_valid_segment(fourth_segment):
# Join the valid segments to form the IP address
ip_address = first_segment + "." + second_segment + "." + third_segment + "." + fourth_segment
possible_ip_addresses.append(ip_address)
return possible_ip_addresses
def is_valid_segment(segment):
# Segments starting with zero must be exactly zero.
if segment.startswith('0') and segment != '0':
return False
# Ensure segments are between 0 and 255.
if int(segment) > 255:
return False
return True
The goal is to find all the valid ways to split a string into four parts, where each part represents a number between 0 and 255. Instead of checking every possible split, the approach breaks down the problem into smaller parts and builds valid IP addresses piece by piece.
Here's how the algorithm would work step-by-step:
def restore_ip_addresses(ip_string):
possible_ip_addresses = []
def is_valid_part(ip_part):
if not ip_part:
return False
if len(ip_part) > 1 and ip_part[0] == '0':
return False
if int(ip_part) > 255:
return False
return True
def backtrack(index, parts, current_ip):
# If we have four parts and have used all characters.
if len(parts) == 4:
if index == len(ip_string):
possible_ip_addresses.append(current_ip[:-1])
return
# Limiting the search space by validating only reasonable parts.
for i in range(index + 1, min(index + 4, len(ip_string) + 1)):
ip_part = ip_string[index:i]
if is_valid_part(ip_part):
# Add current part, and backtrack.
backtrack(i, parts + [ip_part], current_ip + ip_part + '.')
# Begin backtracking with initial conditions
backtrack(0, [], '')
return possible_ip_addresses
Case | How to Handle |
---|---|
Empty input string | Return an empty list immediately as an empty string cannot form a valid IP address. |
Input string length less than 4 | Return an empty list because a valid IP address needs at least 4 digits. |
Input string length greater than 12 | Return an empty list as a valid IP address can have at most 12 digits (4 numbers each up to 3 digits). |
Input string containing non-digit characters | Throw an exception or return an empty list as the problem specifies the input string contains only digits; validating this ensures code robustness. |
Leading zero in a segment, except for a single zero | Reject any segment with a leading zero if its length is greater than 1. |
Segment value greater than 255 | Reject any segment whose integer value is greater than 255. |
No valid IP address possible | The recursive/backtracking algorithm will naturally handle this by not adding any invalid results to the list of valid IP addresses, eventually returning an empty list. |
Integer overflow when converting a string segment to an integer | Use appropriate data types (e.g., `int`) and boundary checks to prevent integer overflow during conversion. |