LeetCode-468. 验证IP地址

难度:中等

编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。

如果是有效的 IPv4 地址,返回 “IPv4” ;
如果是有效的 IPv6 地址,返回 “IPv6” ;
如果不是上述类型的 IP 地址,返回 “Neither” 。
IPv4 地址由十进制数和点来表示,每个地址包含 4 个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1;

同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。

IPv6 地址由 8 组 16 进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。

然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (:😃 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。

同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。

示例:

示例 1:

输入:IP = “172.16.254.1”
输出:“IPv4”
解释:有效的 IPv4 地址,返回 “IPv4”
示例 2:

输入:IP = “2001:0db8:85a3:0:0:8A2E:0370:7334”
输出:“IPv6”
解释:有效的 IPv6 地址,返回 “IPv6”
示例 3:

输入:IP = “256.256.256.256”
输出:“Neither”
解释:既不是 IPv4 地址,又不是 IPv6 地址
示例 4:

输入:IP = “2001:0db8:85a3:0:0:8A2E:0370:7334:”
输出:“Neither”
示例 5:

输入:IP = “1e1.4.5.6”
输出:“Neither”

提示:

IP 仅由英文字母,数字,字符 ‘.’ 和 ‘:’ 组成。

解题思路:

考虑所有边界条件即可:

IPv4:

  • 地址不能以“.”结尾;
  • 段地址数只能为4;
  • 段地址只允许长度为[1,3]区间;
  • 以0开头时只允许长度为1;
  • 段地址只能包含数字;
  • 段地址范围为 0 - 255;

IPv6:

  • 地址不能以“:”结尾
  • 段地址数只能为8;
  • 段地址只允许长度为[1,4]区间;
  • 段地址每个字符必须是合法的16进制字符;

代码实现:

class Solution {
    public String validIPAddress(String IP) {
        if (IP.indexOf(".") != -1) {
            return validateIPv4(IP);
        }
        if (IP.indexOf(":") != -1) {
            return validateIPv6(IP);
        }
        return "Neither";
    }

    /**
     * IPv4校验
     * @param IP IP地址
     * @return 校验结果
     */
    public String validateIPv4(String IP) {
        //地址不能以“.”结尾
        if(IP.endsWith(".")) return "Neither";
        String[] ipv4 = IP.split("\\.");
        //段地址数只能为4;
        if (ipv4.length != 4) return "Neither";
        for (String s : ipv4) {
            //段地址只允许长度为[1,3]区间;
            if (s.length() == 0 || s.length() > 3) return "Neither";
            //以0开头时只允许长度为1;
            if (s.charAt(0) == '0' && s.length() > 1) return "Neither";
            //段地址只能包含数字;
            if (!isNumeric(s)) return "Neither";
            //段地址范围为 0 - 255
            if (Integer.parseInt(s) > 255) return "Neither";
        }
        return "IPv4";
    }

    /**
     * IPv6校验
     * @param IP IP地址
     * @return  校验结果
     */
    public String validateIPv6(String IP) {
        //地址不能以“:”结尾
        if(IP.endsWith(":")) return "Neither";
        String[] ipv6 = IP.split(":");
        //段地址数只能为8;
        if (ipv6.length != 8) return "Neither";
        for (String s : ipv6) {
            //段地址只允许长度为[1,4]区间;
            if (s.length() == 0 || s.length() > 4) return "Neither";
            //段地址每个字符必须是合法的16进制字符
            if (!isHex(s)) return "Neither";
        }
        return "IPv6";
    }

    /**
     * 判断字符串是否是数字串
     * @param str 字符串
     * @return 判断结果
     */
    public static boolean isNumeric(String str){
        for (char c : str.toCharArray()){
            if (!Character.isDigit(c)) return false;
        }
        return true;
    }

    /**
     * 判断字符串是否是有效的十六进制字符串
     * @param str 字符串
     * @return 判断结果
     */
    public static boolean isHex(String str){
        final String number = "0123456789abcedfABCDEF";
        for (char c : str.toCharArray()){
            if(number.indexOf(c) == -1) return false;
        }
        return true;
    }
}

复杂度分析

  • 时间复杂度:O(1)。
  • 空间复杂度:O(1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值