Open In App

Generate Valid IP Addresses from String

Last Updated : 28 Jan, 2025
Suggest changes
Share
Like Article
Like
Report

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 <algorithm> #include <iostream> #include <string> #include <vector> 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<string> &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<string> generateIp(string s) {  vector<string> res;  generateIpRec(s, 0, "", 0, res);  return res; } int main() {  string s = "255678166";  vector<string> 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.


Similar Reads