Дан указатель на начало односвязного списка и два целых числа 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"]

C# решение

сопоставлено/оригинал
public class Solution {
    private int IpToInt(string ip) {
        var parts = ip.Split(new char[] { '.' });
        return (int.Parse(parts[0]) << 24) + (int.Parse(parts[1]) << 16) + 
               (int.Parse(parts[2]) << 8) + int.Parse(parts[3]);
    }
    private string IntToIp(int num) {
        return $"{(num >> 24) & 255}.{(num >> 16) & 255}.{(num >> 8) & 255}.{num & 255}";
    }
    private string Cidr(string ip, int prefixLength) {
        return $"{ip}/{prefixLength}";
    }
    public List<string> FindCidrBlocks(string startIp, int n) {
        int start = IpToInt(startIp);
        var result = new List<string>();
        
        while (n > 0) {
            int maxSize = 1;
            while (maxSize <= start && maxSize <= n) {
                maxSize <<= 1;
            }
            maxSize >>= 1;
            
            while (start % maxSize != 0) {
                maxSize >>= 1;
            }
            
            result.Add(Cidr(IntToIp(start), 32 - BitCount(maxSize - 1) + 1));
            start += maxSize;
            n -= maxSize;
        }
        
        return result;
    }
    private int BitCount(int n) {
        return (int)Math.Log(n, 2) + 1;
    }
}

C++ решение

auto-draft, проверить перед отправкой
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    private int IpToInt(string ip) {
        var parts = ip.Split(new char[] { '.' });
        return (int.Parse(parts[0]) << 24) + (int.Parse(parts[1]) << 16) + 
               (int.Parse(parts[2]) << 8) + int.Parse(parts[3]);
    }
    private string IntToIp(int num) {
        return $"{(num >> 24) & 255}.{(num >> 16) & 255}.{(num >> 8) & 255}.{num & 255}";
    }
    private string Cidr(string ip, int prefixLength) {
        return $"{ip}/{prefixLength}";
    }
    public List<string> FindCidrBlocks(string startIp, int n) {
        int start = IpToInt(startIp);
        var result = new List<string>();
        
        while (n > 0) {
            int maxSize = 1;
            while (maxSize <= start && maxSize <= n) {
                maxSize <<= 1;
            }
            maxSize >>= 1;
            
            while (start % maxSize != 0) {
                maxSize >>= 1;
            }
            
            result.push_back(Cidr(IntToIp(start), 32 - BitCount(maxSize - 1) + 1));
            start += maxSize;
            n -= maxSize;
        }
        
        return result;
    }
    private int BitCount(int n) {
        return (int)Math.Log(n, 2) + 1;
    }
}

Java решение

сопоставлено/оригинал
public class Solution {
    private int ipToInt(String ip) {
        String[] parts = ip.split("\\.");
        return (Integer.parseInt(parts[0]) << 24) + (Integer.parseInt(parts[1]) << 16) +
               (Integer.parseInt(parts[2]) << 8) + Integer.parseInt(parts[3]);
    }

    private String intToIp(int num) {
        return String.format("%d.%d.%d.%d", (num >> 24) & 255, (num >> 16) & 255, (num >> 8) & 255, num & 255);
    }

    private String cidr(String ip, int prefixLength) {
        return ip + "/" + prefixLength;
    }

    public List<String> findCidrBlocks(String startIp, int n) {
        int start = ipToInt(startIp);
        List<String> result = new ArrayList<>();
        
        while (n > 0) {
            int maxSize = 1;
            while (maxSize <= start && maxSize <= n) {
                maxSize <<= 1;
            }
            maxSize >>= 1;
            
            while (start % maxSize != 0) {
                maxSize >>= 1;
            }
            
            result.add(cidr(intToIp(start), 32 - Integer.bitCount(maxSize - 1) + 1));
            start += maxSize;
            n -= maxSize;
        }
        
        return result;
    }
}

JavaScript решение

сопоставлено/оригинал
function ipToInt(ip) {
    const parts = ip.split('.').map(Number);
    return (parts[0] << 24) + (parts[1] << 16) + (parts[2] << 8) + parts[3];
}

function intToIp(num) {
    return `${(num >> 24) & 255}.${(num >> 16) & 255}.${(num >> 8) & 255}.${num & 255}`;
}

function cidr(ip, prefixLength) {
    return `${ip}/${prefixLength}`;
}

function findCidrBlocks(startIp, n) {
    let start = ipToInt(startIp);
    const result = [];
    
    while (n > 0) {
        let maxSize = 1;
        while (maxSize <= start && maxSize <= n) {
            maxSize <<= 1;
        }
        maxSize >>= 1;
        
        while (start % maxSize !== 0) {
            maxSize >>= 1;
        }
        
        result.push(cidr(intToIp(start), 32 - Math.log2(maxSize) | 0 + 1));
        start += maxSize;
        n -= maxSize;
    }
    
    return result;
}

Python решение

сопоставлено/оригинал
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

Go решение

сопоставлено/оригинал
package main

import (
    "fmt"
    "strconv"
    "strings"
)

func ipToInt(ip string) int {
    parts := strings.Split(ip, ".")
    p1, _ := strconv.Atoi(parts[0])
    p2, _ := strconv.Atoi(parts[1])
    p3, _ := strconv.Atoi(parts[2])
    p4, _ := strconv.Atoi(parts[3])
    return (p1 << 24) + (p2 << 16) + (p3 << 8) + p4
}

func intToIp(num int) string {
    return fmt.Sprintf("%d.%d.%d.%d", (num>>24)&255, (num>>16)&255, (num>>8)&255, num&255)
}

func cidr(ip string, prefixLength int) string {
    return fmt.Sprintf("%s/%d", ip, prefixLength)
}

func findCidrBlocks(startIp string, n int) []string {
    start := ipToInt(startIp)
    var result []string
    
    for n > 0 {
        maxSize := 1
        for maxSize <= start && maxSize <= n {
            maxSize <<= 1
        }
        maxSize >>= 1
        
        for start%maxSize != 0 {
            maxSize >>= 1
        }
        
        result = append(result, cidr(intToIp(start), 32-log2(maxSize)+1))
        start += maxSize
        n -= maxSize
    }
    
    return result
}

func log2(n int) int {
    count := 0
    for n > 1 {
        n >>= 1
        count++
    }
    return count
}

Algorithm

Преобразовать начальный IP-адрес в целое число.

Пока количество оставшихся IP-адресов n больше нуля: Определить наибольший блок, который начинается с текущего IP-адреса и не превышает количество оставшихся IP-адресов. Добавить этот блок к результату. Увеличить текущий IP-адрес на размер блока. Уменьшить количество оставшихся IP-адресов n.

Преобразовать блоки обратно в формат CIDR и вернуть их.

😎

Вакансии для этой задачи

Показаны активные вакансии с пересечением по тегам задачи.

Все вакансии
Активных вакансий пока нет.