|
…
|
||
|---|---|---|
| .. | ||
| README.md | ||
| README_EN.md | ||
| Solution.cpp | ||
| Solution.go | ||
| Solution.java | ||
| Solution.py | ||
| Solution.rs | ||
| Solution.ts | ||
README_EN.md
| comments | difficulty | edit_url | tags | |
|---|---|---|---|---|
| true | Medium | https://github.com/doocs/leetcode/edit/main/solution/0400-0499/0468.Validate%20IP%20Address/README_EN.md |
|
468. Validate IP Address
Description
Given a string queryIP, return "IPv4" if IP is a valid IPv4 address, "IPv6" if IP is a valid IPv6 address or "Neither" if IP is not a correct IP of any type.
A valid IPv4 address is an IP in the form "x1.x2.x3.x4" where 0 <= xi <= 255 and xi cannot contain leading zeros. For example, "192.168.1.1" and "192.168.1.0" are valid IPv4 addresses while "192.168.01.1", "192.168.1.00", and "192.168@1.1" are invalid IPv4 addresses.
A valid IPv6 address is an IP in the form "x1:x2:x3:x4:x5:x6:x7:x8" where:
1 <= xi.length <= 4xiis a hexadecimal string which may contain digits, lowercase English letter ('a'to'f') and upper-case English letters ('A'to'F').- Leading zeros are allowed in
xi.
For example, "2001:0db8:85a3:0000:0000:8a2e:0370:7334" and "2001:db8:85a3:0:0:8A2E:0370:7334" are valid IPv6 addresses, while "2001:0db8:85a3::8A2E:037j:7334" and "02001:0db8:85a3:0000:0000:8a2e:0370:7334" are invalid IPv6 addresses.
Example 1:
Input: queryIP = "172.16.254.1" Output: "IPv4" Explanation: This is a valid IPv4 address, return "IPv4".
Example 2:
Input: queryIP = "2001:0db8:85a3:0:0:8A2E:0370:7334" Output: "IPv6" Explanation: This is a valid IPv6 address, return "IPv6".
Example 3:
Input: queryIP = "256.256.256.256" Output: "Neither" Explanation: This is neither a IPv4 address nor a IPv6 address.
Constraints:
queryIPconsists only of English letters, digits and the characters'.'and':'.
Solutions
Solution 1: Simulation
We can define two functions isIPv4 and isIPv6 to determine whether a string is a valid IPv4 address and IPv6 address.
The implementation of the function isIPv4 is as follows:
- We first check if the string
sends with.. If so,sis not a valid IPv4 address, and we directly returnfalse. - Then we split the string
sby.into a string arrayss. If the length ofssis not4,sis not a valid IPv4 address, and we directly returnfalse. - For each string
tin the arrayss, we check:- If the length of
tis greater than1and the first character oftis0,tis not a valid IPv4 address, and we directly returnfalse. - If
tis not a number ortis not in the range of0to255,tis not a valid IPv4 address, and we directly returnfalse.
- If the length of
- If none of the above conditions are met,
sis a valid IPv4 address, and we returntrue.
The implementation of the function isIPv6 is as follows:
- We first check if the string
sends with:. If so,sis not a valid IPv6 address, and we directly returnfalse. - Then we split the string
sby:into a string arrayss. If the length ofssis not8,sis not a valid IPv6 address, and we directly returnfalse. - For each string
tin the arrayss, we check:- If the length of
tis less than1or greater than4,tis not a valid IPv6 address, and we directly returnfalse. - If the characters in
tare not all between0and9andaandf(case insensitive),tis not a valid IPv6 address, and we directly returnfalse.
- If the length of
- If none of the above conditions are met,
sis a valid IPv6 address, and we returntrue.
Finally, we call the isIPv4 and isIPv6 functions to determine if queryIP is a valid IPv4 address or IPv6 address. If it is neither, we return Neither.
The time complexity is O(n), and the space complexity is O(n). Where n is the length of the string queryIP.
Python3
class Solution:
def validIPAddress(self, queryIP: str) -> str:
def is_ipv4(s: str) -> bool:
ss = s.split(".")
if len(ss) != 4:
return False
for t in ss:
if len(t) > 1 and t[0] == "0":
return False
if not t.isdigit() or not 0 <= int(t) <= 255:
return False
return True
def is_ipv6(s: str) -> bool:
ss = s.split(":")
if len(ss) != 8:
return False
for t in ss:
if not 1 <= len(t) <= 4:
return False
if not all(c in "0123456789abcdefABCDEF" for c in t):
return False
return True
if is_ipv4(queryIP):
return "IPv4"
if is_ipv6(queryIP):
return "IPv6"
return "Neither"
Java
class Solution {
public String validIPAddress(String queryIP) {
if (isIPv4(queryIP)) {
return "IPv4";
}
if (isIPv6(queryIP)) {
return "IPv6";
}
return "Neither";
}
private boolean isIPv4(String s) {
if (s.endsWith(".")) {
return false;
}
String[] ss = s.split("\\.");
if (ss.length != 4) {
return false;
}
for (String t : ss) {
if (t.length() == 0 || t.length() > 1 && t.charAt(0) == '0') {
return false;
}
int x = convert(t);
if (x < 0 || x > 255) {
return false;
}
}
return true;
}
private boolean isIPv6(String s) {
if (s.endsWith(":")) {
return false;
}
String[] ss = s.split(":");
if (ss.length != 8) {
return false;
}
for (String t : ss) {
if (t.length() < 1 || t.length() > 4) {
return false;
}
for (char c : t.toCharArray()) {
if (!Character.isDigit(c)
&& !"0123456789abcdefABCDEF".contains(String.valueOf(c))) {
return false;
}
}
}
return true;
}
private int convert(String s) {
int x = 0;
for (char c : s.toCharArray()) {
if (!Character.isDigit(c)) {
return -1;
}
x = x * 10 + (c - '0');
if (x > 255) {
return x;
}
}
return x;
}
}
C++
class Solution {
public:
string validIPAddress(string queryIP) {
if (isIPv4(queryIP)) {
return "IPv4";
}
if (isIPv6(queryIP)) {
return "IPv6";
}
return "Neither";
}
private:
bool isIPv4(const string& s) {
if (s.empty() || s.back() == '.') {
return false;
}
vector<string> ss = split(s, '.');
if (ss.size() != 4) {
return false;
}
for (const string& t : ss) {
if (t.empty() || (t.size() > 1 && t[0] == '0')) {
return false;
}
int x = convert(t);
if (x < 0 || x > 255) {
return false;
}
}
return true;
}
bool isIPv6(const string& s) {
if (s.empty() || s.back() == ':') {
return false;
}
vector<string> ss = split(s, ':');
if (ss.size() != 8) {
return false;
}
for (const string& t : ss) {
if (t.size() < 1 || t.size() > 4) {
return false;
}
for (char c : t) {
if (!isxdigit(c)) {
return false;
}
}
}
return true;
}
int convert(const string& s) {
int x = 0;
for (char c : s) {
if (!isdigit(c)) {
return -1;
}
x = x * 10 + (c - '0');
if (x > 255) {
return x;
}
}
return x;
}
vector<string> split(const string& s, char delimiter) {
vector<string> tokens;
string token;
istringstream iss(s);
while (getline(iss, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
};
Go
func validIPAddress(queryIP string) string {
if isIPv4(queryIP) {
return "IPv4"
}
if isIPv6(queryIP) {
return "IPv6"
}
return "Neither"
}
func isIPv4(s string) bool {
if strings.HasSuffix(s, ".") {
return false
}
ss := strings.Split(s, ".")
if len(ss) != 4 {
return false
}
for _, t := range ss {
if len(t) == 0 || (len(t) > 1 && t[0] == '0') {
return false
}
x := convert(t)
if x < 0 || x > 255 {
return false
}
}
return true
}
func isIPv6(s string) bool {
if strings.HasSuffix(s, ":") {
return false
}
ss := strings.Split(s, ":")
if len(ss) != 8 {
return false
}
for _, t := range ss {
if len(t) < 1 || len(t) > 4 {
return false
}
for _, c := range t {
if !unicode.IsDigit(c) && !strings.ContainsRune("0123456789abcdefABCDEF", c) {
return false
}
}
}
return true
}
func convert(s string) int {
x := 0
for _, c := range s {
if !unicode.IsDigit(c) {
return -1
}
x = x*10 + int(c-'0')
if x > 255 {
return x
}
}
return x
}
TypeScript
function validIPAddress(queryIP: string): string {
if (isIPv4(queryIP)) {
return 'IPv4';
}
if (isIPv6(queryIP)) {
return 'IPv6';
}
return 'Neither';
}
function isIPv4(s: string): boolean {
if (s.endsWith('.')) {
return false;
}
const ss = s.split('.');
if (ss.length !== 4) {
return false;
}
for (const t of ss) {
if (t.length === 0 || (t.length > 1 && t[0] === '0')) {
return false;
}
const x = convert(t);
if (x < 0 || x > 255) {
return false;
}
}
return true;
}
function isIPv6(s: string): boolean {
if (s.endsWith(':')) {
return false;
}
const ss = s.split(':');
if (ss.length !== 8) {
return false;
}
for (const t of ss) {
if (t.length < 1 || t.length > 4) {
return false;
}
for (const c of t) {
if (!isHexDigit(c)) {
return false;
}
}
}
return true;
}
function convert(s: string): number {
let x = 0;
for (const c of s) {
if (!isDigit(c)) {
return -1;
}
x = x * 10 + (c.charCodeAt(0) - '0'.charCodeAt(0));
if (x > 255) {
return x;
}
}
return x;
}
function isDigit(c: string): boolean {
return c >= '0' && c <= '9';
}
function isHexDigit(c: string): boolean {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
Rust
impl Solution {
pub fn valid_ip_address(query_ip: String) -> String {
if Self::is_ipv4(&query_ip) {
return "IPv4".to_string();
}
if Self::is_ipv6(&query_ip) {
return "IPv6".to_string();
}
"Neither".to_string()
}
fn is_ipv4(s: &str) -> bool {
if s.ends_with('.') {
return false;
}
let ss: Vec<&str> = s.split('.').collect();
if ss.len() != 4 {
return false;
}
for t in ss {
if t.is_empty() || (t.len() > 1 && t.starts_with('0')) {
return false;
}
match Self::convert(t) {
Some(x) if x <= 255 => {
continue;
}
_ => {
return false;
}
}
}
true
}
fn is_ipv6(s: &str) -> bool {
if s.ends_with(':') {
return false;
}
let ss: Vec<&str> = s.split(':').collect();
if ss.len() != 8 {
return false;
}
for t in ss {
if t.len() < 1 || t.len() > 4 {
return false;
}
if !t.chars().all(|c| c.is_digit(16)) {
return false;
}
}
true
}
fn convert(s: &str) -> Option<i32> {
let mut x = 0;
for c in s.chars() {
if !c.is_digit(10) {
return None;
}
x = x * 10 + (c.to_digit(10).unwrap() as i32);
if x > 255 {
return Some(x);
}
}
Some(x)
}
}