Generate Valid IP Addresses from String (original) (raw)
Last Updated : 28 Jan, 2025
Given a **String containing only **digits, the task is to restore it by returning all **possible valid IP address combinations.
A valid **IP address must be in the form of **A.B.C.D, where A, B, C, and D are numbers from **0-255. The numbers cannot be **0 prefixed unless they are 0.
**Examples:
**Input: “255678166”
**Output: [“25.56.78.166”, “255.6.78.166”, “255.67.8.166”, “255.67.81.66”]
**Explanation: These are the only valid possible IP addresses.**Input: “25505011535”
**Output: []
**Explanation: We cannot generate a valid IP address with this string.
Approach – Using Backtracking with pruning
The idea is to use **backtracking and prune recursive branches that would lead to invalid **IP addresses.
An **IP address consists of **4 valid numbers separated by **3 dots. We have to place these 3 dots at **positions such that 4 valid numbers are formed.One key observation is that the **next dot can be placed **1, 2, or 3 positions after the **last dot, as the numbers formed must not **exceed 255. Additionally, before placing a dot, we **check if the **current number being formed is **valid or invalid. If the number is invalid, we will **backtrack and explore other available options.
**Step by Step implementation
- First place dots in the string to form valid IP segments.
- Check whether the current segment is valid before continuing. If it is invalid prune that recursive branch.
- Stop once 3 dots are placed, ensuring the final segment is valid. C++ `
// C++ program to generate all possible valid // ip address using backtracking
#include #include #include #include
using namespace std;
// Function to check whether segment is valid or not. bool isValid(string &s) { int n = s.size();
// Segment of lenght one are always valid
if (n == 1)
return true;
// converting string into integer
int val = stoi(s);
// Invalid case: If it has preceding zero or
// if its value is greater than 255.
if (s[0] == '0' || val > 255)
return false;
return true;
}
// Recursive helper Function to generate valid IP address void generateIpRec(string &s, int index, string curr, int cnt, vector &res) { string temp = "";
// Base case: Reached end of string and
// all 4 segments were not completed
if (index >= s.size())
return;
if (cnt == 3) {
temp = s.substr(index);
// Checking 4th(last) segment of ip address
if (temp.size() <= 3 && isValid(temp) )
res.push_back(curr+temp);
return;
}
for (int i = index; i < min(index + 3, (int)s.size()); i++) {
// creating next segment of ip address.
temp = temp + s[i];
// If the created segment is valid.
if (isValid(temp)) {
// Generate the remaining segments of IP
generateIpRec(s, i + 1, curr + temp + '.', cnt + 1, res);
}
}
}
// Function to generate valid IP address vector generateIp(string s) { vector res;
generateIpRec(s, 0, "", 0, res);
return res;
}
int main() { string s = "255678166"; vector res = generateIp(s);
for (string ip : res)
cout << ip << endl;
}
Java
// Java program to generate all possible valid // ip address using backtracking import java.util.ArrayList;
class GfG {
// Function to check whether segment is valid or not.
static boolean isValid(String s) {
int n = s.length();
// Segment of length one is always valid
if (n == 1)
return true;
// Converting string into integer
int val = Integer.parseInt(s);
// Invalid case: If it has a preceding zero or
// its value is greater than 255.
if (s.charAt(0) == '0' || val > 255)
return false;
return true;
}
// Recursive helper function to generate valid IP address
static void generateIpRec(String s, int index, String curr,
int cnt, ArrayList<String> res) {
String temp = "";
// Base case: Reached end of string and
// all 4 segments were not completed
if (index >= s.length())
return;
if (cnt == 3) {
temp = s.substring(index);
// Checking 4th (last) segment of IP address
if (temp.length() <= 3 && isValid(temp))
res.add(curr + temp);
return;
}
for (int i = index; i < Math.min(index + 3, s.length()); i++) {
// Creating next segment of IP address
temp += s.charAt(i);
// If the created segment is valid
if (isValid(temp)) {
// Generate the remaining segments of IP
generateIpRec(s, i + 1, curr + temp + ".", cnt + 1, res);
}
}
}
// Function to generate valid IP address
static ArrayList<String> generateIp(String s) {
ArrayList<String> res = new ArrayList<>();
generateIpRec(s, 0, "", 0, res);
return res;
}
public static void main(String[] args) {
String s = "255678166";
ArrayList<String> res = generateIp(s);
for (String ip : res)
System.out.println(ip);
}
}
Python
Python program to generate all possible valid
ip address using backtracking
Function to check whether segment is valid or not.
def isValid(s): n = len(s)
# Segment of length one is always valid
if n == 1:
return True
# Converting string into integer
val = int(s)
# Invalid case: If it has a preceding zero or
# its value is greater than 255
if s[0] == '0' or val > 255:
return False
return True
Recursive helper function to generate valid IP address
def generateIpRec(s, index, curr, cnt, res): temp = ""
# Base case: Reached end of string and
# all 4 segments were not completed
if index >= len(s):
return
if cnt == 3:
temp = s[index:]
# Checking 4th (last) segment of IP address
if len(temp) <= 3 and isValid(temp):
res.append(curr + temp)
return
for i in range(index, min(index + 3, len(s))):
# Creating next segment of IP address
temp += s[i]
# If the created segment is valid
if isValid(temp):
# Generate the remaining segments of IP
generateIpRec(s, i + 1, curr + temp + ".", cnt + 1, res)
Function to generate valid IP address
def generateIp(s): res = [] generateIpRec(s, 0, "", 0, res) return res
if name == "main": s = "255678166" res = generateIp(s)
for ip in res:
print(ip)
C#
// C# program to generate all possible valid // ip address using backtracking using System; using System.Collections.Generic;
class GfG { // Function to check whether segment is valid or not. static bool isValid(string s) { int n = s.Length;
// Segment of length one is always valid
if (n == 1)
return true;
// Converting string into integer
int val = int.Parse(s);
// Invalid case: If it has a preceding zero or
// its value is greater than 255.
if (s[0] == '0' || val > 255)
return false;
return true;
}
// Recursive helper function to generate valid IP address
static void generateIpRec(string s, int index, string curr,
int cnt, List<string> res) {
string temp = "";
// Base case: Reached end of string and
// all 4 segments were not completed
if (index >= s.Length)
return;
if (cnt == 3) {
temp = s.Substring(index);
// Checking 4th (last) segment of IP address
if (temp.Length <= 3 && isValid(temp))
res.Add(curr + temp);
return;
}
for (int i = index; i < Math.Min(index + 3, s.Length); i++) {
// Creating next segment of IP address
temp += s[i];
// If the created segment is valid
if (isValid(temp)) {
// Generate the remaining segments of IP
generateIpRec(s, i + 1, curr + temp + ".", cnt + 1, res);
}
}
}
// Function to generate valid IP address
static List<string> generateIp(string s) {
List<string> res = new List<string>();
generateIpRec(s, 0, "", 0, res);
return res;
}
static void Main(string[] args) {
string s = "255678166";
List<string> res = generateIp(s);
foreach (string ip in res)
Console.WriteLine(ip);
}
}
JavaScript
// JavaScript program to generate all possible valid // ip address using backtracking
// Function to check whether segment is valid or not. function isValid(s) { const n = s.length;
// Segment of length one is always valid
if (n === 1)
return true;
// Converting string into integer
const val = parseInt(s, 10);
// Invalid case: If it has a preceding zero or
// its value is greater than 255
if (s[0] === '0' || val > 255)
return false;
return true;
}
// Recursive helper function to generate valid IP address function generateIpRec(s, index, curr, cnt, res) { let temp = "";
// Base case: Reached end of string and
// all 4 segments were not completed
if (index >= s.length)
return;
if (cnt === 3) {
temp = s.substring(index);
// Checking 4th (last) segment of IP address
if (temp.length <= 3 && isValid(temp))
res.push(curr + temp);
return;
}
for (let i = index; i < Math.min(index + 3, s.length); i++) {
// Creating next segment of IP address
temp += s[i];
// If the created segment is valid
if (isValid(temp)) {
// Generate the remaining segments of IP
generateIpRec(s, i + 1, curr + temp + ".", cnt + 1, res);
}
}
}
// Function to generate valid IP address function generateIp(s) { const res = []; generateIpRec(s, 0, "", 0, res); return res; }
// Driver code const s = "255678166"; const res = generateIp(s); res.forEach(ip => console.log(ip));
`
Output
25.56.78.166 255.6.78.166 255.67.8.166 255.67.81.66
**Time complexity: O(27*n) = O(n), since total 3 times recursive call is made and number of branches in each recursive call is 3.
**Auxiliary Space: O(n), used by temporary strings.