751. IP to CIDR
LeetCode
medium
original: C#
#bit-manipulation
#csharp
#leetcode
#linked-list
#math
#medium
#prefix-sum
#search
#string
#two-pointers
選択した UI 言語に合わせて問題文をロシア語から翻訳します。コードは変更しません。
Дан указатель на начало односвязного списка и два целых числа 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++ 解法
自動ドラフト、提出前に確認#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 и вернуть их.
😎
Vacancies for this task
有効な求人 with overlapping task tags are 表示.
有効な求人はまだありません。