План курса / Все задачи / Алгоритмы и структуры данных
Перебор IP-адресов
средне
Дана строка s, состоящая только из цифр. Необходимо вернуть все возможные корректные IP-адреса, которые можно получить путём расстановки трёх точек. Возвращаемые IP-адреса могут быть в любом порядке.
IP-адрес состоит из четырёх чисел (октетов), разделённых точками. Каждый октет должен быть:
числом от 0 до 255
без ведущих нулей, кроме самого нуля (т.е. "0" — допустимо, "01" — нет)
Пример 1:
Ввод: s = "25525511135"
Вывод: ["255.255.11.135","255.255.111.35"]
Пример 2:
Ввод: s = "0000"
Вывод: ["0.0.0.0"]
Пример 3:
Ввод: s = "101023"
Вывод: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
Ограничения:
1 ≤ len(s) ≤ 20
s состоит только из цифр ('0'–'9')
public class Solution {
private static void Bruteforce(string s, int num, int start, List<string> partial, List<string> result) {
// Если собрано 4 октета и строка исчерпана — сохраняем IP
if (num > 4) {
if (start == s.Length) {
result.Add(string.Join(".", partial));
}
return;
}
// Осталось слишком мало символов — смысла продолжать нет
int remaining = s.Length - start;
if (remaining < 4 - num) return;
// Перебираем длину октета (1–3 символа, если не последний)
int maxLen = (num == 4) ? remaining : Math.Min(3, remaining);
for (int l = 1; l <= maxLen; l++) {
string part = s.Substring(start, l);
// Отсеиваем варианты с ведущими нулями
if (l > 1 && part[0] == '0') break;
// Число должно быть не больше 255
if (int.Parse(part) > 255) break;
partial.Add(part);
Bruteforce(s, num + 1, start + l, partial, result);
partial.RemoveAt(partial.Count - 1);
}
}
// Восстанавливает все возможные корректные IP-адреса из строки
public static List<string> RestoreIp(string s) {
List<string> result = new List<string>();
Bruteforce(s, 1, 0, new List<string>(), result);
return result;
}
}
#include <vector>
#include <string>
using namespace std;
void bruteforce(string& s, int num, int start, vector<string>& partial, vector<string>& result) {
// Если собрано 4 октета и строка исчерпана — сохраняем IP
if (num > 4) {
if (start == s.length()) {
string ip = partial[0];
for (int i = 1; i < 4; ++i) {
ip += "." + partial[i];
}
result.push_back(ip);
}
return;
}
// Осталось слишком мало символов — смысла продолжать нет
int remaining = s.length() - start;
if (remaining < 4 - num) return;
// Перебираем длину октета (1–3 символа, если не последний)
int maxLen = (num == 4) ? remaining : min(3, remaining);
for (int l = 1; l <= maxLen; ++l) {
string part = s.substr(start, l);
// Отсеиваем варианты с ведущими нулями
if (l > 1 && part[0] == '0') break;
// Число должно быть не больше 255
if (stoi(part) > 255) break;
partial.push_back(part);
bruteforce(s, num + 1, start + l, partial, result);
partial.pop_back();
}
}
vector<string> restoreIp(string& s) {
vector<string> result;
vector<string> partial;
bruteforce(s, 1, 0, partial, result);
return result;
}
package main
import (
"strconv"
)
func bruteforce(s string, num int, start int, partial []string, result *[]string) {
// Если собрано 4 октета и строка исчерпана — сохраняем IP
if num > 4 {
if start == len(s) {
ip := partial[0]
for i := 1; i < 4; i++ {
ip += "." + partial[i]
}
*result = append(*result, ip)
}
return
}
// Осталось слишком мало символов — смысла продолжать нет
remaining := len(s) - start
if remaining < 4 - num {
return
}
// Перебираем длину октета (1–3 символа, если не последний)
maxLen := remaining
if num != 4 && remaining > 3 {
maxLen = 3
}
for l := 1; l <= maxLen; l++ {
part := s[start : start+l]
// Отсеиваем варианты с ведущими нулями
if l > 1 && part[0] == '0' {
break
}
// Число должно быть не больше 255
val, _ := strconv.Atoi(part)
if val > 255 {
break
}
partial = append(partial, part)
bruteforce(s, num+1, start+l, partial, result)
partial = partial[:len(partial)-1]
}
}
func restoreIp(s string) []string {
result := []string{}
bruteforce(s, 1, 0, []string{}, &result)
return result
}
import java.util.*;
public class Solution {
private void bruteforce(String s, int num, int start, List<String> partial, List<String> result) {
// Если собрано 4 октета и строка исчерпана — сохраняем IP
if (num > 4) {
if (start == s.length()) {
result.add(String.join(".", partial));
}
return;
}
// Осталось слишком мало символов — смысла продолжать нет
int remaining = s.length() - start;
if (remaining < 4 - num) return;
// Перебираем длину октета (1–3 символа, если не последний)
int maxLen = (num == 4) ? remaining : Math.min(3, remaining);
for (int l = 1; l <= maxLen; l++) {
String part = s.substring(start, start + l);
// Отсеиваем варианты с ведущими нулями
if (l > 1 && part.charAt(0) == '0') break;
// Число должно быть не больше 255
if (Integer.parseInt(part) > 255) break;
partial.add(part);
bruteforce(s, num + 1, start + l, partial, result);
partial.remove(partial.size() - 1);
}
}
// Восстанавливает все возможные корректные IP-адреса из строки
public List<String> restoreIp(String s) {
List<String> result = new ArrayList<>();
bruteforce(s, 1, 0, new ArrayList<>(), result);
return result;
}
}
from typing import *
def bruteforce(s: str, num: int, start: int, partial: List[str], result: List[str]) -> None:
# Если собрано 4 октета и строка исчерпана — сохраняем IP
if num > 4:
if start == len(s):
result.append('.'.join(partial))
return
# Осталось слишком мало символов — смысла продолжать нет
remaining = len(s) - start
if remaining < 4 - num:
return
# Перебираем длину октета (1–3 символа, если не последний)
max_len = remaining if num == 4 else min(3, remaining)
for l in range(1, max_len + 1):
part = s[start:start + l]
# Отсеиваем варианты с ведущими нулями
if l > 1 and part[0] == '0':
break
# Число должно быть не больше 255
if int(part) > 255:
break
partial.append(part)
bruteforce(s, num + 1, start + l, partial, result)
partial.pop()
# Восстанавливает все возможные корректные IP-адреса из строки
def restore_ip(s: str) -> List[str]:
result = []
bruteforce(s, 1, 0, [], result)
return result
/**
* @param {string} s
* @return {string[]}
*/
export function restoreIp(s) {
const result = [];
function bruteforce(s, num, start, partial) {
// Если собрано 4 октета и строка исчерпана — сохраняем IP
if (num > 4) {
if (start === s.length) {
result.push(partial.join('.'));
}
return;
}
// Осталось слишком мало символов — смысла продолжать нет
const remaining = s.length - start;
if (remaining < 4 - num) return;
// Перебираем длину октета (1–3 символа, если не последний)
const maxLen = (num === 4) ? remaining : Math.min(3, remaining);
for (let l = 1; l <= maxLen; l++) {
const part = s.substring(start, start + l);
// Отсеиваем варианты с ведущими нулями
if (l > 1 && part[0] === '0') break;
// Число должно быть не больше 255
if (parseInt(part) > 255) break;
partial.push(part);
bruteforce(s, num + 1, start + l, partial);
partial.pop();
}
}
bruteforce(s, 1, 0, []);
return result;
}
Оценка сложности
Время: O(1) — ограниченное число верных комбинаций
Память: O(1) — ограниченное число верных комбинаций