Restore IP Addresses In C,CPP,JAVA,PYTHON,C#,JS

Spread the love
A close-up shot of a person coding on a laptop, focusing on the hands and screen.

Problem Statement: Restore IP Addresses

Given a string s containing only digits, restore it by returning all possible valid IP address combinations.

A valid IP address consists of exactly four integers separated by periods (.), where each integer is between 0 and 255 (inclusive), and no integer has leading zeros unless it is “0”.

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 = "1111"

Output:

["1.1.1.1"]

Approach

To solve this problem, we can use backtracking or depth-first search (DFS) to explore all possible valid IP address combinations. Each valid IP address consists of four parts, each part being a number between 0 and 255, and each part must not have leading zeros unless it is exactly “0”.

Key Constraints:

  1. The string must be split into exactly four segments.
  2. Each segment should be a number between 0 and 255.
  3. The segment should not contain leading zeros unless it is exactly “0”.
  4. The total length of the string s should be between 4 and 12 to form a valid IP address (since each segment must contain at least one digit).

Plan:

  1. Backtracking:
    • Split the string into 4 parts using backtracking.
    • For each part, check if the part is a valid number (i.e., in the range 0-255 and does not have leading zeros unless it is “0”).
  2. Base Case: Once we have four valid parts, join them using dots (.) and add them to the result.
  3. Recursive Case: Try different segment lengths (1 to 3 characters) for each part and recursively explore the remaining string.

Time Complexity:

  • Time Complexity: O(n^3), where n is the length of the string. We are exploring all combinations of three split points and checking if each part is valid.
  • Space Complexity: O(n), where n is the length of the string. We store the current result in the backtracking process.

Code Implementation

C Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void backtrack(char *s, int start, int part, char *current, char **result, int *resultCount) {
if (part == 4) {
if (start == strlen(s)) {
result[*resultCount] = strdup(current);
(*resultCount)++;
}
return;
}

for (int len = 1; len <= 3; len++) {
if (start + len > strlen(s)) break;
char temp[len + 1];
strncpy(temp, s + start, len);
temp[len] = '\0';

// Check validity of the segment
if ((len == 1) || (temp[0] != '0' && atoi(temp) <= 255)) {
char nextCurrent[100];
snprintf(nextCurrent, sizeof(nextCurrent), "%s%s%s", current, (part == 0 ? "" : "."), temp);
backtrack(s, start + len, part + 1, nextCurrent, result, resultCount);
}
}
}

char** restoreIpAddresses(char* s, int* returnSize) {
char **result = (char **)malloc(100 * sizeof(char*));
*returnSize = 0;
if (strlen(s) < 4 || strlen(s) > 12) return result;

backtrack(s, 0, 0, "", result, returnSize);
return result;
}

int main() {
char s[] = "25525511135";
int returnSize = 0;
char **result = restoreIpAddresses(s, &returnSize);

printf("Possible IPs:\n");
for (int i = 0; i < returnSize; i++) {
printf("%s\n", result[i]);
free(result[i]);
}
free(result);
return 0;
}

C++ Code

#include <iostream>
#include <vector>
#include <string>
using namespace std;

void backtrack(string& s, int start, int part, string current, vector<string>& result) {
if (part == 4) {
if (start == s.size()) {
result.push_back(current);
}
return;
}

for (int len = 1; len <= 3; len++) {
if (start + len > s.size()) break;
string temp = s.substr(start, len);

// Check validity of the segment
if ((len == 1) || (temp[0] != '0' && stoi(temp) <= 255)) {
backtrack(s, start + len, part + 1, current + (part == 0 ? "" : ".") + temp, result);
}
}
}

vector<string> restoreIpAddresses(string s) {
vector<string> result;
if (s.size() < 4 || s.size() > 12) return result;
backtrack(s, 0, 0, "", result);
return result;
}

int main() {
string s = "25525511135";
vector<string> result = restoreIpAddresses(s);

cout << "Possible IPs:" << endl;
for (const string& ip : result) {
cout << ip << endl;
}
return 0;
}

Java Code

import java.util.ArrayList;
import java.util.List;

public class RestoreIPAddresses {

private void backtrack(String s, int start, int part, String current, List<String> result) {
if (part == 4) {
if (start == s.length()) {
result.add(current);
}
return;
}

for (int len = 1; len <= 3; len++) {
if (start + len > s.length()) break;
String temp = s.substring(start, start + len);

// Check validity of the segment
if ((len == 1) || (temp.charAt(0) != '0' && Integer.parseInt(temp) <= 255)) {
backtrack(s, start + len, part + 1, current + (part == 0 ? "" : ".") + temp, result);
}
}
}

public List<String> restoreIpAddresses(String s) {
List<String> result = new ArrayList<>();
if (s.length() < 4 || s.length() > 12) return result;
backtrack(s, 0, 0, "", result);
return result;
}

public static void main(String[] args) {
RestoreIPAddresses solution = new RestoreIPAddresses();
String s = "25525511135";
List<String> result = solution.restoreIpAddresses(s);

System.out.println("Possible IPs:");
for (String ip : result) {
System.out.println(ip);
}
}
}

Python Code

def restoreIpAddresses(s):
result = []

def backtrack(start, part, current):
if part == 4:
if start == len(s):
result.append(current)
return

for length in range(1, 4):
if start + length > len(s):
break
temp = s[start:start + length]

# Check validity of the segment
if (length == 1) or (temp[0] != '0' and int(temp) <= 255):
backtrack(start + length, part + 1, current + ('.' if part > 0 else '') + temp)

if len(s) < 4 or len(s) > 12:
return result

backtrack(0, 0, "")
return result

# Example usage
s = "25525511135"
result = restoreIpAddresses(s)

print("Possible IPs:")
for ip in result:
print(ip)

C# Code

using System;
using System.Collections.Generic;

public class RestoreIPAddresses
{
private void Backtrack(string s, int start, int part, string current, List<string> result)
{
if (part == 4)
{
if (start == s.Length)
{
result.Add(current);
}
return;
}

for (int len = 1; len <= 3; len++)
{
if (start + len > s.Length) break;
string temp = s.Substring(start, len);

// Check validity of the segment
if (len == 1 || (temp[0] != '0' && int.Parse(temp) <= 255))
{
Backtrack(s, start + len, part + 1, current + (part == 0 ? "" : ".") + temp, result);
}
}
}

public List<string> RestoreIpAddresses(string s)
{
List<string> result = new List<string>();
if (s.Length < 4 || s.Length > 12) return result;
Backtrack(s, 0, 0, "", result);
return result;
}

public static void Main()
{
string s = "25525511135";
RestoreIPAddresses solution = new RestoreIPAddresses();
var result = solution.RestoreIpAddresses(s);

Console.WriteLine("Possible IPs:");
foreach (var ip in result)
{
Console.WriteLine(ip);
}
}
}

JavaScript Code

const restoreIpAddresses = (s) => {
const result = [];

const backtrack = (start, part, current) => {
if (part === 4) {
if (start === s.length) {
result.push(current);
}
return;
}

for (let len = 1; len <= 3; len++) {
if (start + len > s.length) break;
const temp = s.slice(start, start + len);

// Check validity of the segment
if (len === 1 || (temp[0] !== '0' && parseInt(temp) <= 255)) {
backtrack(start + len, part + 1, current + (part === 0 ? "" : ".") + temp);
}
}
};

if (s.length < 4 || s.length > 12) return result;

backtrack(0, 0, "");
return result;
};

// Example usage
const s = "25525511135";
const result = restoreIpAddresses(s);

console.log("Possible IPs:");
result.forEach(ip => console.log(ip));

Explanation:

  1. Backtracking: We recursively explore all possible segments by iterating over 1 to 3 characters and checking their validity.
  2. Validity Check: Each segment must be a number between 0 and 255 and should not contain leading zeros unless it is “0”.
  3. Base Case: If we have exactly 4 valid parts and the entire string has been consumed, we add the current combination to the result.

Time and Space Complexity:

  • Time Complexity: O(n^3), where n is the length of the input string s. We generate all combinations of splits and for each split check if the segments are valid.
  • Space Complexity: O(n), for storing intermediate results during backtracking.