1、解题思路
- 回溯法: 递归地尝试在每个位置插入分隔符(.),确保每个段满足IP地址的条件。终止条件:已经插入三个分隔符,且剩余字符串也满足条件。剪枝条件: 字符串太长或太短(总长度应在4到12之间)。当前段的数字不在[0,255]范围内。当前段有前导零且长度大于1。
- 条件检查: 段长度不超过3。段数字不超过255。段不能有前导零(除非是"0"本身)。
2、代码实现
C++
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @return string字符串vector
*/
vector<string> restoreIpAddresses(string s) {
// write code here
vector<string> result;
backtrack(s, 0, "", 0, result);
return result;
}
private:
void backtrack(string s, int index, string current, int count, vector<string>& result) {
if (count == 4) {
if (index == s.size()) {
result.push_back(current);
}
return ;
}
for (int i = 1; i <= 3 && index + i <= s.size(); ++i) {
string segment = s.substr(index, i);
if (isValid(segment)) {
string new_current = current + segment + (count == 3 ? "" : ".");
backtrack(s, index + i, new_current, count + 1, result);
}
}
}
bool isValid(string segment) {
if (segment.size() > 1 && segment[0] == '0') {
return false;
}
int num = stoi(segment);
return num >= 0 && num <= 255;
}
};
Java
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @return string字符串ArrayList
*/
public ArrayList<String> restoreIpAddresses (String s) {
// write code here
ArrayList<String> result = new ArrayList<>();
backtrack(s, 0, "", 0, result);
return result;
}
private void backtrack(String s, int index, String current, int count, ArrayList<String> result) {
if (count == 4) {
if (index == s.length()) {
result.add(current);
}
return;
}
for (int i = 1; i <= 3 && index + i <= s.length(); i++) {
String segment = s.substring(index, index + i);
if (isValid(segment)) {
String newCurrent = current + segment + (count == 3 ? "" : ".");
backtrack(s, index + i, newCurrent, count + 1, result);
}
}
}
private boolean isValid(String segment) {
if (segment.length() > 1 && segment.charAt(0) == '0') {
return false;
}
int num = Integer.parseInt(segment);
return num >= 0 && num <= 255;
}
}
Python
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param s string字符串
# @return string字符串一维数组
#
class Solution:
def restoreIpAddresses(self , s: str) -> List[str]:
# write code here
result = []
self.backtrack(s, 0, "", 0, result)
return result
def backtrack(self, s: str, index: int, current: str, count: int, result: List[str]) -> None:
if count == 4:
if index == len(s):
result.append(current)
return
for i in range(1, 4):
if index + i > len(s):
break
segment = s[index:index + i]
if self.is_valid(segment):
new_current = current + segment + ("" if count == 3 else ".")
self.backtrack(s, index + i, new_current, count + 1, result)
def is_valid(self, segment: str) -> bool:
if len(segment) > 1 and segment[0] == '0':
return False
num = int(segment)
return 0 <= num <= 255
3、复杂度分析
- 递归终止条件: 已经插入三个分隔符(.),且剩余字符串为空。
- 剪枝条件: 当前段长度不超过3。当前段数字在[0,255]范围内。当前段不能有前导零(除非是"0"本身)。
- 复杂度分析: 时间复杂度:O(n!),因为每个位置的分隔符选择都影响后续的选择。空间复杂度:O(n!),存储所有可能的合法IP地址。
进阶思考
- 如果需要优化剪枝条件,可以在递归前先检查字符串长度(4 ≤
n≤ 12)。 - 如果需要处理更长的字符串(如
n≤ 20),可以考虑动态规划或其他优化方法。

京公网安备 11010502036488号