LeetCode 468. 验证IP地址【C++/Java详细题解】

「这是我参与2022首次更文挑战的第34天,活动详情查看:2022首次更文挑战

1、题目

给定一个字符串 queryIP。如果是有效的 IPv4 地址,返回 "IPv4";如果是有效的 IPv6 地址,返回 "IPv6" ;如果不是上述类型的 IP 地址,返回 "Neither"

有效的IPv4地址“x1.x2.x3.x4” 形式的IP地址。 其中 0 <= xi <= 255xi 不能包含 前导零。例如: “192.168.1.1”“192.168.1.0”为有效IPv4地址, “192.168.01.1” 为无效IPv4地址; “192.168.1.00”[email protected] 为无效IPv4地址。

一个有效的IPv6地址 是一个格式为“x1:x2:x3:x4:x5:x6:x7:x8” 的IP地址,其中:

  • 1 <= xi.length <= 4
  • xi是一个 十六进制字符串 ,可以包含数字、小写英文字母('a''f')和大写英文字母('A''F' )。
  • xi 中允许前导零。

比如, 2001:0db8:85a3::8A2E:0370:73342001:db8:85a3:0:0:8A2E:0370:7334 是有效的 IPv6 地址。而 2001:0db8:85a3::8A2E:037j:733402001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。

示例 1:

 输入:queryIP = "172.16.254.1"
 输出:"IPv4"
 解释:有效的 IPv4 地址,返回 "IPv4"
复制代码

示例 2:

 输入:queryIP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
 输出:"IPv6"
 解释:有效的 IPv6 地址,返回 "IPv6"
复制代码

示例 3:

 输入:queryIP = "256.256.256.256"
 输出:"Neither"
 解释:既不是 IPv4 地址,又不是 IPv6 地址
复制代码

提示:

  • queryIP 仅由英文字母,数字,字符 '.'':' 组成。

2、思路

(字符串 + 模拟) O(n)

一个合法的IPv4满足以下条件:

  1. .分割成4组字符串。
  2. 每组字符串不为空,且长度<= 3
  3. 每组字符串转换成数字后介于0 ~ 255之间。
  4. 每组字符串仅由数字字符组成。
  5. 每组字符串的长度大于1时,不包含前导0

一个合法的IPv6满足以下条件:

  1. :分割成8组字符串。
  2. 每组字符串不为空,且长度<= 4
  3. 每组字符串转化成数字后为一个16进制数,即字符范围为: 0~9,a~f, A~F

由于C++中没有按字符分割的函数,因此我们自定义一个分割函数split,如下:

 vector<string> split(string ip, char t) {
         vector<string> items;
         for (int i = 0; i < ip.size(); i ++ ) {
             int j = i;
             string item;
             while (ip[j] != t) item += ip[j ++ ];
             i = j;
             items.push_back(item);
         }
         return items;
    } 
复制代码

这里使用了双指针算法,传入一个要分割的字符串ip和分割字符t,最后返回分割好的字符串数组items

判断一个合法的IPv4和IPv6,我们首先调用分割函数split,然后按照上述条件模拟即可。

具体过程如下:

  • 1、如果一个字符串ip即包含.也包含:,我们直接返回Neither
  • 2、如果包含.,我们进行check_ipv4(ip),IPv4的合法性判断。
  • 3、如果包含:,我们进行check_ipv6(ip),IPv6的合法性判断。

时间复杂度分析: 每个字符串仅会被遍历一遍,因此时间复杂度为O(n)。

3、c++代码

 class Solution {
 public:
     vector<string> split(string ip, char t){
         vector<string> items;
         for(int i = 0; i < ip.size(); i++){
             int j = i;
             string item;
             while(j < ip.size() && ip[j] != t)  item += ip[j++];
             i = j;
             items.push_back(item);  
         }
         return items;
     }
     string check_ipv4(string ip){
         auto items = split(ip + '.', '.');a
         if(items.size() != 4) return "Neither";
         for(string item : items){
             if(item.empty() || item.size() > 3) return "Neither";
             if(item.size() > 1 && item[0] == '0')   return "Neither";
             for(char c : item){
                 if(c < '0' || c > '9') return "Neither";
             }
             int t = stoi(item);
             if(t > 255) return "Neither";
         }
         return "IPv4";
     }
     bool check(char c){
         if (c >= '0' && c <= '9') return true;
         if (c >= 'a' && c <= 'f') return true;
         if (c >= 'A' && c <= 'F') return true;
         return false;
     }
     string check_ipv6(string ip){
         auto items = split(ip + ':', ':');
         if(items.size() != 8) return "Neither";
         for(string item : items){
             if(item.empty() || item.size() > 4) return "Neither";
             for(char c : item){
                 if(!check(c)) return "Neither"; 
             }
         }
         return "IPv6";
     }
 ​
     string validIPAddress(string ip) {
         if(ip.find('.') != -1 && ip.find(':') != -1) return "Neither";
         if(ip.find('.') != -1)  return check_ipv4(ip);
         if(ip.find(':') != -1)  return check_ipv6(ip);
         return "Neither";
     }
 };
复制代码

4、Java代码

public String validIPAddress(String ip) {
    if (ip.indexOf('.') != -1 && ip.indexOf(':') != -1) return "Neither";
    if (ip.indexOf('.') != -1) return checkIPv4(ip);
    if (ip.indexOf(':') != -1) return checkIPv6(ip);
    return "Neither";
}

private String checkIPv4(String ip) {
    String[] items = ip.split("\\.");
    if (items.length != 4  || ip.charAt(ip.length() - 1) == '.') return "Neither";
    for (String item : items) {
        if (item.isEmpty() || item.length() > 3) return "Neither";
        if (item.length() > 1 && item.charAt(0) == '0') return "Neither";
        for (int i = 0; i < item.length(); i++)
            if (item.charAt(i) < '0' || item.charAt(i) > '9') return "Neither";
        int t = Integer.parseInt(item);
        if (t > 255) return "Neither";
    }
    return "IPv4";
}

private String checkIPv6(String ip) {
    String[] items = ip.split(":");
    if (items.length != 8 || ip.charAt(ip.length() - 1) == ':') return "Neither";
    for (String item : items) {
        if (item.isEmpty() || item.length() > 4) return "Neither";
        for (int i = 0; i < item.length(); i++)
            if (!check(item.charAt(i))) return "Neither";
    }
    return "IPv6";
}

private boolean check(char c) {
    if (c >= '0' && c <= '9') return true;
    if (c >= 'a' && c <= 'f') return true;
    if (c >= 'A' && c <= 'F') return true;
    return false;
}

复制代码

猜你喜欢

转载自juejin.im/post/7067171738685014052