leetcode刷题记录-468. 验证IP地址

146 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

前言

今天的题目为中等,难点应该是在于判断每一个IP都是情况都需要考虑的比较多,但是每一种情况都是可以模拟出来的,有点耐心解决这道题的难度应该是不大的,就是会需要耗费比较多的时间。

每日一题

今天的题目是 468. 验证IP地址,难度为中等

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

  • 有效的IPv4地址 是 “x1.x2.x3.x4” 形式的IP地址。 其中 0 <= xi <= 255 且 xi 不能包含 前导零。例如: “192.168.1.1” 、 “192.168.1.0” 为有效IPv4地址, “192.168.01.1” 为无效IPv4地址; “192.168.1.00” 、 “192.168@1.1” 为无效IPv4地址。

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

  • 1 <= xi.length <= 4

  • xi 是一个 十六进制字符串 ,可以包含数字、小写英文字母( 'a' 到 'f' )和大写英文字母( 'A' 到 'F' )。

  • 在 xi 中允许前导零。

  • 例如 "2001:0db8:85a3:0000:0000:8a2e:0370:7334" 和 "2001:db8:85a3:0:0:8A2E:0370:7334" 是有效的 IPv6 地址,而 "2001:0db8:85a3::8A2E:037j:7334" 和 "02001:0db8:85a3:0000:0000:8a2e:0370:7334" 是无效的 IPv6 地址。

 

示例 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 仅由英文字母,数字,字符 '.' 和 ':' 组成。

题解

简单模拟

根据题目的要求能够进行简单模拟,模拟出每一种情况,只是这种方式会需要编写比较多的代码,从字符串中含有 '.' 或者 ':' 来判断地址是IPv4或者IPv6。

IPv4

对于IPv4来说,需要将字符串对'.'进行分割,分割后得到的数组必须是4个,并且要满足三个条件:

  1. 字符串中不包含字母
  2. 字符串中不存在前导0,也就是当分割后的数组元素长度大于1的时候,开头字符不能够是0
  3. 字符串拼接起来得到的数字要在0-255这个范围当中

根据这几点进行简单模拟,我们就能够得到一个用以验证字符串是不是IPv4的函数:

function IP4checked(queryIP: string): boolean{
    let ip = queryIP.split('.')
    if(ip.length!=4){
        return false
    }
    for(let i=0;i<ip.length;i++){
        if (ip[i].length > 3 || ip[i].length == 0 || (ip[i].length > 1 && ip[i].charCodeAt(0) == 48)) {
            return false
        }
         let cur = 0
        for (let j = 0; j < ip[i].length; j++) {
            if (ip[i].charCodeAt(j) <= '9'.charCodeAt(0) && ip[i].charCodeAt(j) >= '0'.charCodeAt(0)) {
                cur = 10 * cur + ip[i].charCodeAt(j) - '0'.charCodeAt(0)
            } else {
                return false
            }
        }
        if (cur > 255) {
            return false
        }
    }
    return true
}

IPv6

对于IPv6来说判断要稍微简单一点,IPv6是相对于':'进行分割,并且分割后的数组长度需要为8。并且还需要满足两个条件,在IPv6中,是允许前导0的存在的,所以不需要判断

  1. 数组的每一项的长度需要在1-4之间
  2. 数组的每一项需要是由数组0-9或者字母a-f或者字母A-F组成

根据这几点条件,我们就也能够写出验证IPv6的函数:

function IP6checked(queryIP: string): boolean{
    const ip = queryIP.split(":")
    if (ip.length != 8) {
        return false
    }
    for (const s of ip) {
        if (s.length > 4 || s.length == 0) {
            return false
        }
        for (let i = 0; i < s.length; i++) {
            const c = s.charCodeAt(i)
            if (! (('0'.charCodeAt(0) <= c && c <= '9'.charCodeAt(0)) || ('a'.charCodeAt(0) <= c && 'f'.charCodeAt(0) >= c) || ('A'.charCodeAt(0) <= c && c <= 'F'.charCodeAt(0)))) {
                return false
            }
        }
    }
    return true
}

解题

综上两个函数,我们能够通过判断字符串里面含有的是'.'或者':'来判断IP为IPv4或者IPv6,都不是的话就可以返回"Neither".

function validIPAddress(queryIP: string): string {
    if(IP4checked(queryIP)){
        return "IPv4"
    }
    if(IP6checked(queryIP)){
        return "IPv6"
    }
    return "Neither"
};



image.png