从给定字符串生成所有可能的有效 IP 地址的程序
给定一个只包含数字的字符串,通过返回所有可能的有效 IP 地址组合来恢复它。
有效的 IP 地址必须采用 ABCD 格式,其中 A、B、C 和 D 是 0-255 之间的数字。数字不能以 0 为前缀,除非它们是 0。
例子 :
Input: 25525511135
Output: [“255.255.11.135”, “255.255.111.35”]
Explanation:
These are the only valid possible
IP addresses.
Input: "25505011535"
Output: []
Explanation:
We cannot generate a valid IP
address with this string.
首先,我们将在给定的字符串中放置 3 个点,然后尝试这 3 个点的所有可能组合。
有效性的角落案例:
For string "25011255255"
25.011.255.255 is not valid as 011 is not valid.
25.11.255.255 is not valid either as you are not
allowed to change the string.
250.11.255.255 is valid.
方法:用 ' 分割字符串。 ' 然后检查所有极端情况。在进入循环之前,检查字符串的大小。使用循环字符串生成所有可能的组合。如果发现 IP 有效,则返回 IP 地址,否则只返回空列表。
下面是上述方法的实现:
C++
// C++ program to generate all possible
// valid IP addresses from given string
#include
using namespace std;
// Function checks whether IP digits
// are valid or not.
int is_valid(string ip)
{
// Splitting by "."
vector ips;
string ex = "";
for (int i = 0; i < ip.size(); i++) {
if (ip[i] == '.') {
ips.push_back(ex);
ex = "";
}
else {
ex = ex + ip[i];
}
}
ips.push_back(ex);
// Checking for the corner cases
// cout << ip << endl;
for (int i = 0; i < ips.size(); i++) {
// cout << ips[i] < 3
|| stoi(ips[i]) < 0
|| stoi(ips[i]) > 255)
return 0;
if (ips[i].length() > 1
&& stoi(ips[i]) == 0)
return 0;
if (ips[i].length() > 1
&& stoi(ips[i]) != 0
&& ips[i][0] == '0')
return 0;
}
return 1;
}
// Function converts string to IP address
void convert(string ip)
{
int l = ip.length();
// Check for string size
if (l > 12 || l < 4) {
cout << "Not Valid IP Address";
}
string check = ip;
vector ans;
// Generating different combinations.
for (int i = 1; i < l - 2; i++) {
for (int j = i + 1; j < l - 1; j++) {
for (int k = j + 1; k < l; k++) {
check = check.substr(0, k) + "."
+ check.substr(k);
check
= check.substr(0, j) + "."
+ check.substr(j);
check
= check.substr(0, i) + "."
+ check.substr(i);
// cout<< check <
Java
// Java Program to generate all possible
// valid IP addresses from given string
import java.util.*;
class GFG {
// Function to restore Ip Addresses
public static ArrayList
restoreIpAddresses(String A)
{
if (A.length() < 3 || A.length() > 12)
return new ArrayList<>();
return convert(A);
}
private static ArrayList
convert(String s)
{
ArrayList l = new ArrayList<>();
int size = s.length();
String snew = s;
for (int i = 1; i < size - 2;
i++) {
for (int j = i + 1;
j < size - 1; j++) {
for (int k = j + 1;
k < size; k++) {
snew
= snew.substring(0, k) + "."
+ snew.substring(k);
snew
= snew.substring(0, j) + "."
+ snew.substring(j);
snew
= snew.substring(0, i) + "."
+ snew.substring(i);
if (isValid(snew)) {
l.add(snew);
}
snew = s;
}
}
}
Collections.sort(l, new Comparator() {
public int compare(String o1, String o2)
{
String a1[] = o1.split("[.]");
String a2[] = o2.split("[.]");
int result = -1;
for (int i = 0; i < 4
&& result != 0;
i++) {
result = a1[i].compareTo(a2[i]);
}
return result;
}
});
return l;
}
private static boolean isValid(String ip)
{
String a[] = ip.split("[.]");
for (String s : a) {
int i = Integer.parseInt(s);
if (s.length() > 3 || i < 0 || i > 255) {
return false;
}
if (s.length() > 1 && i == 0)
return false;
if (s.length() > 1 && i != 0
&& s.charAt(0) == '0')
return false;
}
return true;
}
// Driver Code
public static void main(String[] args)
{
System.out.println(
restoreIpAddresses(
"25525511135")
.toString());
}
}
// This code is contributed by Nidhi Hooda.
Python3
# Python3 code to check valid possible IP
# Function checks whether IP digits
# are valid or not.
def is_valid(ip):
# Splitting by "."
ip = ip.split(".")
# Checking for the corner cases
for i in ip:
if (len(i) > 3 or int(i) < 0 or
int(i) > 255):
return False
if len(i) > 1 and int(i) == 0:
return False
if (len(i) > 1 and int(i) != 0 and
i[0] == '0'):
return False
return True
# Function converts string to IP address
def convert(s):
sz = len(s)
# Check for string size
if sz > 12:
return []
snew = s
l = []
# Generating different combinations.
for i in range(1, sz - 2):
for j in range(i + 1, sz - 1):
for k in range(j + 1, sz):
snew = snew[:k] + "." + snew[k:]
snew = snew[:j] + "." + snew[j:]
snew = snew[:i] + "." + snew[i:]
# Check for the validity of combination
if is_valid(snew):
l.append(snew)
snew = s
return l
# Driver code
A = "25525511135"
B = "25505011535"
print(convert(A))
print(convert(B))
Javascript
Java
// Java Program to generate all possible
// valid IP addresses from given string
import java.util.*;
class GFG
{
public static ArrayList list;
// Function to restore Ip Addresses
public static ArrayList
restoreIpAddresses(String s)
{
int n = s.length();
list = new ArrayList<>();
if (n < 4 || n > 12)
return list;
// initialize the dp array
int dp[][] = new int[4][n];
for (int i = 0; i < 4; i++)
{
for (int j = n - 1; j >= 0; j--)
{
if (i == 0)
{
// take the substring
String sub = s.substring(j);
if (isValid(sub))
{
dp[i][j] = 1;
}
else if (j < n - 3)
{
break;
}
}
else
{
if (j <= n - i)
{
for (int k = 1;
k <= 3 && j + k <= n;
k++)
{
String temp
= s.substring(j, j + k);
if (isValid(temp))
{
if (j + k < n
&& dp[i - 1][j + k]
== 1)
{
dp[i][j] = 1;
break;
}
}
}
}
}
}
}
if (dp[3][0] == 0)
return list;
// Call function createfromDp
createIpFromDp(dp, 3, 0, s, "");
return list;
}
public static void createIpFromDp(int dp[][],
int r,
int c, String s,
String ans)
{
if (r == 0)
{
ans += s.substring(c);
list.add(ans);
return;
}
for (int i = 1;
i <= 3 && c + i < s.length();
i++)
{
if (isValid(s.substring(c, c + i))
&& dp[r - 1] == 1)
{
createIpFromDp(dp, r - 1, c + i, s,
ans +
s.substring(c, c + i)
+ ".");
}
}
}
private static boolean isValid(String ip)
{
String a[] = ip.split("[.]");
for (String s : a)
{
int i = Integer.parseInt(s);
if (s.length() > 3 || i < 0 || i > 255)
{
return false;
}
if (s.length() > 1 && i == 0)
return false;
if (s.length() > 1 && i != 0
&& s.charAt(0) == '0')
return false;
}
return true;
}
// Driver Code
public static void main(String[] args)
{
// Function call
System.out.println(
restoreIpAddresses("25525511135").toString());
}
}
// This code is contributed by Nidhi Hooda.
C++
#include
#include
using namespace std;
void solve(string s, int i, int j, int level, string temp,
vector& res)
{
if (i == (j + 1) && level == 5) {
res.push_back(temp.substr(1));
}
// Digits of a number ranging 0-255 can lie only between
// 0-3
for (int k = i; k < i + 3 && k <= j; k++) {
string ad = s.substr(i, k - i + 1);
// Return if sting starting with '0' or it is
// greater than 255.
if ((s[i] == '0'&&ad.size()>1) || stol(ad) > 255)
return;
// Recursively call for another level.
solve(s, k + 1, j, level + 1, temp + '.' + ad, res);
}
}
int main()
{
string s = "25525511135";
int n = s.length();
vector ans;
solve(s, 0, n - 1, 1, "", ans);
for (string s : ans)
cout << s << endl;
return 0;
}
255.255.11.135
255.255.111.35
复杂性分析:
- 时间复杂度: O(n^3),其中 n 是字符串的长度
需要对字符串进行三次嵌套遍历,其中 n 始终小于 12。 - 辅助空间: O(n)。
因为需要额外的空间。
另一种有效的方法(动态规划):对于这个问题存在一种 dp 方法,可以在时间复杂度 O(n*4*3)=O(12n)=O(n) 和空间复杂度 O(4n) 中解决。
方法:我们知道IP只有4个部分。我们从字符串的开头。我们创建一个大小为 (4 x N) 的 dp 二维数组。 dp 数组中只能有 2 个值,即 1(真)或 0(假)。 dp[0][i] 告诉我们是否可以从从 i 开始到字符串结尾的子字符串创建 IP 的 1 部分。类似地, dp[1][i] 告诉我们是否可以从从 i 开始到字符串结尾的子字符串创建 IP 的 2 部分。
创建 dp 数组后,我们开始创建有效的 IP 地址。我们从 2D dp 数组的左下角开始。我们只迭代 12 次(最坏情况),但这些也将是有效的 IP 地址,因为我们只形成有效的 IP 地址。
Java
// Java Program to generate all possible
// valid IP addresses from given string
import java.util.*;
class GFG
{
public static ArrayList list;
// Function to restore Ip Addresses
public static ArrayList
restoreIpAddresses(String s)
{
int n = s.length();
list = new ArrayList<>();
if (n < 4 || n > 12)
return list;
// initialize the dp array
int dp[][] = new int[4][n];
for (int i = 0; i < 4; i++)
{
for (int j = n - 1; j >= 0; j--)
{
if (i == 0)
{
// take the substring
String sub = s.substring(j);
if (isValid(sub))
{
dp[i][j] = 1;
}
else if (j < n - 3)
{
break;
}
}
else
{
if (j <= n - i)
{
for (int k = 1;
k <= 3 && j + k <= n;
k++)
{
String temp
= s.substring(j, j + k);
if (isValid(temp))
{
if (j + k < n
&& dp[i - 1][j + k]
== 1)
{
dp[i][j] = 1;
break;
}
}
}
}
}
}
}
if (dp[3][0] == 0)
return list;
// Call function createfromDp
createIpFromDp(dp, 3, 0, s, "");
return list;
}
public static void createIpFromDp(int dp[][],
int r,
int c, String s,
String ans)
{
if (r == 0)
{
ans += s.substring(c);
list.add(ans);
return;
}
for (int i = 1;
i <= 3 && c + i < s.length();
i++)
{
if (isValid(s.substring(c, c + i))
&& dp[r - 1] == 1)
{
createIpFromDp(dp, r - 1, c + i, s,
ans +
s.substring(c, c + i)
+ ".");
}
}
}
private static boolean isValid(String ip)
{
String a[] = ip.split("[.]");
for (String s : a)
{
int i = Integer.parseInt(s);
if (s.length() > 3 || i < 0 || i > 255)
{
return false;
}
if (s.length() > 1 && i == 0)
return false;
if (s.length() > 1 && i != 0
&& s.charAt(0) == '0')
return false;
}
return true;
}
// Driver Code
public static void main(String[] args)
{
// Function call
System.out.println(
restoreIpAddresses("25525511135").toString());
}
}
// This code is contributed by Nidhi Hooda.
[255.255.11.135, 255.255.111.35]
复杂性分析:
- 时间复杂度:O(n),其中 n 是字符串的长度。 dp 数组的创建需要 O(4*n*3) = O(12n) = O(n)。从 dp 数组创建有效的 IP 需要 O(n)。
- 辅助空间:O(n)。由于 dp 数组有额外的空间大小(4 xn)。这意味着 O(4n)。
另一种方法:(使用递归)
C++
#include
#include
using namespace std;
void solve(string s, int i, int j, int level, string temp,
vector& res)
{
if (i == (j + 1) && level == 5) {
res.push_back(temp.substr(1));
}
// Digits of a number ranging 0-255 can lie only between
// 0-3
for (int k = i; k < i + 3 && k <= j; k++) {
string ad = s.substr(i, k - i + 1);
// Return if sting starting with '0' or it is
// greater than 255.
if ((s[i] == '0'&&ad.size()>1) || stol(ad) > 255)
return;
// Recursively call for another level.
solve(s, k + 1, j, level + 1, temp + '.' + ad, res);
}
}
int main()
{
string s = "25525511135";
int n = s.length();
vector ans;
solve(s, 0, n - 1, 1, "", ans);
for (string s : ans)
cout << s << endl;
return 0;
}
255.255.11.135
255.255.111.35