Сложность: medium
Дан указатель на начало односвязного списка и два целых числа left и right, где left <= right. Необходимо перевернуть узлы списка, начиная с позиции left и заканчивая позицией right, и вернуть измененный список.
Пример:
Input: ip = "255.0.0.7", n = 10
Output: ["255.0.0.7/32","255.0.0.8/29","255.0.0.16/32"]
👨💻 Алгоритм:
1⃣Преобразовать начальный IP-адрес в целое число.
2⃣Пока количество оставшихся IP-адресов n больше нуля: Определить наибольший блок, который начинается с текущего IP-адреса и не превышает количество оставшихся IP-адресов. Добавить этот блок к результату. Увеличить текущий IP-адрес на размер блока. Уменьшить количество оставшихся IP-адресов n.
3⃣Преобразовать блоки обратно в формат CIDR и вернуть их.
😎 Решение:
def ip_to_int(ip):
parts = ip.split('.')
return (int(parts[0]) << 24) + (int(parts[1]) << 16) + (int(parts[2]) << 8) + int(parts[3])
def int_to_ip(num):
return f"{(num >> 24) & 255}.{(num >> 16) & 255}.{(num >> 8) & 255}.{num & 255}"
def cidr(ip, prefix_length):
return f"{ip}/{prefix_length}"
def find_cidr_blocks(start_ip, n):
start = ip_to_int(start_ip)
result = []
while n > 0:
max_size = 1
while max_size <= start and max_size <= n:
max_size <<= 1
max_size >>= 1
while start % max_size != 0:
max_size >>= 1
result.append(cidr(int_to_ip(start), 32 - max_size.bit_length() + 1))
start += max_size
n -= max_size
return result
Ставь 👍 и забирай 📚 Базу знаний