题目描述

这是 LeetCode 上的 468. 验证IP地址 ,难度为 中等

Tag : 「模拟」、「双指针」

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

有效的 IPv4 地址 是 “x1.x2.x3.x4” 形式的 IP 地址。 其中  且   不能包含 前导零。

例如: “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 地址,其中:

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

例如 "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 中由 ./: 分割的部分称为 item

无论是 IPv4 还是 IPv6,我们都只需将连续段的 item 取出,并结合题意判断即可,一个较为简单的方式使用 split 操作来得到所有的 item,考虑到某些语言并不内置 split,这里采取双指针的方式来做。

为方便大家理解,今天将题解文字说明写到注释中。

代码:

class Solution {    public String validIPAddress(String ip) {        if (ip.indexOf(".") >= 0 && check4(ip)) return "IPv4";        if (ip.indexOf(":") >= 0 && check6(ip)) return "IPv6";        return "Neither";    }    boolean check4(String ip) {        int n = ip.length(), cnt = 0;        char[] cs = ip.toCharArray();        for (int i = 0; i < n && cnt <= 3; ) {            // 找到连续数字段,以 x 存取            int j = i, x = 0;            while (j < n && cs[j] >= '0' && cs[j] <= '9' && x <= 255) x = x * 10 + (cs[j++] - '0');            // 非 item 字符之间没有 item            if (i == j) return false;            // 含前导零 或 数值大于 255            if ((j - i > 1 && cs[i] == '0') || (x > 255)) return false;            i = j + 1;            if (j == n) continue;            // 存在除 . 以外的其他非数字字符            if (cs[j] != '.') return false;            cnt++;        }        // 恰好存在 3 个不位于两端的 .        return cnt == 3 && cs[0] != '.' && cs[n - 1] != '.';    }    boolean check6(String ip) {        int n = ip.length(), cnt = 0;        char[] cs = ip.toCharArray();        for (int i = 0; i < n && cnt <= 7; ) {            int j = i;            while (j < n && ((cs[j] >= 'a' && cs[j] <= 'f') || (cs[j] >= 'A' && cs[j] <= 'F') || (cs[j] >= '0' && cs[j] <= '9'))) j++;            // 非 item 字符之间没有 item 或 长度超过 4            if (i == j || j - i > 4) return false;            i = j + 1;            if (j == n) continue;            // 存在除 : 以外的其他非数字字符            if (cs[j] != ':') return false;            cnt++;        }        // 恰好存在 7 个不位于两段的 :        return cnt == 7 && cs[0] != ':' && cs[n - 1] != ':';    }}
  • 时间复杂度:
  • 空间复杂度:使用 toCharArray 操作会产生新数组,复杂度为 ,使用 charAt 操作代替复杂度为

最后

这是我们「刷穿 LeetCode」系列文章的第 No.468 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。


本文由 mdnice 多平台发布

【宫水三叶的刷题日记】468. 验证IP地址相关推荐

  1. 【宫水三叶的刷题日记】961. 在长度 2N 的数组中找出重复 N 次的元素

    题目描述 这是 LeetCode 上的 961. 在长度 2N 的数组中找出重复 N 次的元素 ,难度为 简单. Tag : 「模拟」.「计数」.「构造」.「哈希表」 给你一个整数数组 nums ,该 ...

  2. 【宫水三叶的刷题日记】1022. 从根到叶的二进制数之和

    题目描述 这是 LeetCode 上的 1022. 从根到叶的二进制数之和 ,难度为 简单. Tag : 「DFS」.「BFS」.「二叉树」.「树的遍历」 给出一棵二叉树,其上每个结点的值都是   或 ...

  3. 【宫水三叶的刷题日记】1037. 有效的回旋镖(简单)

    题目描述 这是 LeetCode 上的 1037. 有效的回旋镖 ,难度为 简单. Tag : 「计算几何」.「数学」 给定一个数组 points,其中   表示 X-Y 平面上的一个点,如果这些点构 ...

  4. 【宫水三叶的刷题日记】497. 非重叠矩形中的随机点(中等)

    题目描述 这是 LeetCode 上的 497. 非重叠矩形中的随机点 ,难度为 中等. Tag : 「前缀和」.「二分」.「随机化」 给定一个由非重叠的轴对齐矩形的数组 rects,其中 表示 是第 ...

  5. 【宫水三叶的刷题日记】732. 我的日程安排表 III

    题目描述 这是 LeetCode 上的 「732. 我的日程安排表 III」 ,难度为 「困难」. Tag : 「线段树(动态开点)」.「分块」.「线段树」 当 个日程安排有一些时间上的交叉时(例如 ...

  6. 【宫水三叶的刷题日记】209. 长度最小的子数组(中等)

    题目描述 这是 LeetCode 上的 209. 长度最小的子数组 ,难度为 中等. Tag : 「前缀和」.「二分」 给定一个含有 n 个正整数的数组和一个正整数 target. 找出该数组中满足其 ...

  7. 【宫水三叶的刷题日记】715. Range 模块

    题目描述 这是 LeetCode 上的 715. Range 模块 ,难度为 困难. Tag : 「线段树」.「线段树(动态开点)」 Range 模块是跟踪数字范围的模块.设计一个数据结构来跟踪表示为 ...

  8. 【宫水三叶的刷题日记】730. 统计不同回文子序列(困难)

    题目描述 这是 LeetCode 上的 730. 统计不同回文子序列 ,难度为 困难. Tag : 「区间 DP」.「动态规划」 给定一个字符串 s,返回 s 中不同的非空「回文子序列」个数 . 通过 ...

  9. 【宫水三叶的刷题日记】508. 出现次数最多的子树元素和

    题目描述 这是 LeetCode 上的 508. 出现次数最多的子树元素和 ,难度为 中等. Tag : 「树的遍历」.「DFS」.「哈希表」 给你一个二叉树的根结点 root,请返回出现次数最多的子 ...

最新文章

  1. bios x86保护模式下的软盘操作floppy
  2. 2012年河南省普通高校招生本科一批院校 平行投档分数线(理科)
  3. Python-图像的手绘效果
  4. linux搭建ca服务器搭建,linux下安装EJBCA 搭建私有CA服务器
  5. Name node is in safe mode解决
  6. 【计蒜客 - 蓝桥训练】炮台实验(数学期望,期望dp)
  7. 博客更新内容简单介绍
  8. 彻底搞懂oracle字符集,搞懂oracle字符集
  9. 如何用结构型信号量实现互斥和同步
  10. Emacs远程开发及projectile安装
  11. Windows移动开发(三)——闭关修炼
  12. HCIE-Security Day20:GRE协议:实验(一)配置基于静态路由的GRE隧道
  13. InDesign 教程,如何创建沉浸式文档?
  14. 《Lua程序设计》第7章 迭代器与泛型for 学习笔记
  15. 狼人杀微信娱乐游戏小程序源码
  16. Typora-Markdown编辑器语法
  17. 如何录制Gif动态图片
  18. C#维特智能蓝牙5.0加速度陀螺仪角度姿态传感器协议解析
  19. python 导入本地模块包失败的解决方案
  20. 验证信用卡c语言,信用卡卡号验证算法

热门文章

  1. 小张Markdown 学习小白篇
  2. oracle的种子文件,Oracle用RMAN还原种子数据库
  3. 微信小程序循环 wxfor、wxfor-item(s)区别与联系、data-xxx、wx-key使用
  4. html 将button居中
  5. 炼丹师入门修炼指南-深度学习入门资料推荐
  6. Docker打包发布
  7. 腾讯云cos上传文件功能封装
  8. 职场智慧:10部电影教你6大沟通术
  9. MySQL数据库--数据库复制
  10. 多方位测试一下for循环不同写法的性能差别