Generate Valid IP Addresses from String (original) (raw)

Last Updated : 28 Jan, 2025

Try it on GfG Practice redirect icon

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

// 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.