20. 表示数值的字符串

ops/2024/9/22 23:59:53/

comments: true
difficulty: 中等
edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9820.%20%E8%A1%A8%E7%A4%BA%E6%95%B0%E5%80%BC%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2/README.md

[面试题 20. 表示数值的字符串]逻辑题(https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/)

题目描述

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

数值(按顺序)可以分成以下几个部分:

  1. 若干空格
  2. 一个 小数 或者 整数
  3. (可选)一个 'e''E' ,后面跟着一个 整数
  4. 若干空格

小数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+''-'
  2. 下述格式之一:
    1. 至少一位数字,后面跟着一个点 '.'
    2. 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
    3. 一个点 '.' ,后面跟着至少一位数字

整数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+''-'
  2. 至少一位数字

部分数值列举如下:

  • ["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]

部分非数值列举如下:

  • ["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]

示例 1:

输入:s = "0"
输出:true

示例 2:

输入:s = "e"
输出:false

示例 3:

输入:s = "."
输出:false

示例 4:

输入:s = "    .1  "
输出:true

提示:

  • 1 <= s.length <= 20
  • s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.'

解法

方法一:分类讨论

我们先去除字符串 s s s 首尾的空格,此时 i i i j j j 分别指向字符串 s s s 的第一个非空格字符和最后一个非空格字符。

然后我们维护以下几个变量,其中:

  • digit:表示是否出现过数字
  • dot:表示是否出现过点
  • e:表示是否出现过 e 或者 E

遍历 s [ i , . . j ] s[i,..j] s[i,..j] 范围内的每个字符,根据字符的类型进行分类讨论:

  • 如果当前字符是 + 或者 -,那么该字符的前一个字符必须是 e 或者 E,或者空格,否则返回 false
  • 如果当前字符是数字,那么我们将 digit 置为 true
  • 如果当前字符是 .,那么该字符之前不能出现过 . 或者 e/E,否则返回 false,否则(在满足情况下我们将 dot 置为 true
  • 如果当前字符是 e 或者 E,那么该字符之前不能出现过 e/E,并且必须出现过数字,否则返回 false,否则(在满足情况下)我们将 e 置为 true,并且将 digit 置为 false,表示 e 之后必须出现数字。
  • 如果当前字符是其它字符,那么返回 false

遍历结束后,我们返回 digit,即是否出现过数字。

时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)。其中 n n n 为字符串 s s s 的长度。

Python3
class Solution:def isNumber(self, s: str) -> bool:i, j = 0, len(s) - 1while i < j and s[i] == " ":i += 1while i <= j and s[j] == " ":j -= 1if i > j:return Falsedigit = dot = e = Falsewhile i <= j:if s[i] in "+-":if i and s[i - 1] not in " eE":return Falseelif s[i].isdigit():digit = Trueelif s[i] == ".":if dot or e:return Falsedot = Trueelif s[i] in "eE":if not digit or e:return Falsee, digit = True, Falseelse:return Falsei += 1return digit
Java
class Solution {public boolean isNumber(String s) {int i = 0, j = s.length() - 1;while (i < j && s.charAt(i) == ' ') {++i;}while (i <= j && s.charAt(j) == ' ') {--j;}if (i > j) {return false;}boolean digit = false;boolean dot = false;boolean e = false;for (; i <= j; ++i) {if (s.charAt(i) == '+' || s.charAt(i) == '-') {if (i > 0 && s.charAt(i - 1) != ' ' && s.charAt(i - 1) != 'e'&& s.charAt(i - 1) != 'E') {return false;}} else if (Character.isDigit(s.charAt(i))) {digit = true;} else if (s.charAt(i) == '.') {if (dot || e) {return false;}dot = true;} else if (s.charAt(i) == 'e' || s.charAt(i) == 'E') {if (!digit || e) {return false;}e = true;digit = false;} else {return false;}}return digit;}
}
C++
class Solution {
public:bool isNumber(string s) {int i = 0, j = s.size() - 1;while (i < j && s[i] == ' ') {++i;}while (i <= j && s[j] == ' ') {--j;}if (i > j) {return false;}bool digit = false, dot = false, e = false;for (; i <= j; ++i) {if (s[i] == '+' || s[i] == '-') {if (i && s[i - 1] != ' ' && s[i - 1] != 'e' && s[i - 1] != 'E') {return false;}} else if (isdigit(s[i])) {digit = true;} else if (s[i] == '.') {if (dot || e) {return false;}dot = true;} else if (s[i] == 'e' || s[i] == 'E') {if (!digit || e) {return false;}e = true;digit = false;} else {return false;}}return digit;}
};
Go
func isNumber(s string) bool {i, j := 0, len(s)-1for i < j && s[i] == ' ' {i++}for i <= j && s[j] == ' ' {j--}if i > j {return false}digit, dot, e := false, false, falsefor ; i <= j; i++ {if s[i] == '+' || s[i] == '-' {if i > 0 && s[i-1] != ' ' && s[i-1] != 'e' && s[i-1] != 'E' {return false}} else if s[i] >= '0' && s[i] <= '9' {digit = true} else if s[i] == '.' {if dot || e {return false}dot = true} else if s[i] == 'e' || s[i] == 'E' {if !digit || e {return false}digit, e = false, true} else {return false}}return digit
}
C#
public class Solution {public bool IsNumber(string s) {int i = 0, j = s.Length - 1;while (i < j && s[i] == ' ') {++i;}while (i <= j && s[j] == ' ') {--j;}if (i > j) {return false;}bool digit = false, dot = false, e = false;for (; i <= j; ++i) {if (s[i] == '+' || s[i] == '-') {if (i > 0 && s[i - 1] != ' ' && s[i - 1] != 'e' && s[i - 1] != 'E') {return false;}} else if (s[i] >= '0' && s[i] <= '9') {digit = true;} else if (s[i] == '.') {if (dot || e) {return false;}dot = true;} else if (s[i] == 'e' || s[i] == 'E') {if (!digit || e) {return false;}e = true;digit = false;} else {return false;}}return digit;}
}
Swift
class Solution {func isNumber(_ s: String) -> Bool {let chars = Array(s)var i = 0, j = chars.count - 1// Trim leading spaceswhile i <= j && chars[i] == " " {i += 1}// Trim trailing spaceswhile i <= j && chars[j] == " " {j -= 1}if i > j {return false}var digit = falsevar dot = falsevar e = falsewhile i <= j {let char = chars[i]if char == "+" || char == "-" {if i > 0 && chars[i - 1] != " " && chars[i - 1] != "e" && chars[i - 1] != "E" {return false}} else if char.isWholeNumber {digit = true} else if char == "." {if dot || e {return false}dot = true} else if char == "e" || char == "E" {if !digit || e {return false}e = truedigit = false} else {return false}i += 1}return digit}
}

http://www.ppmy.cn/ops/98002.html

相关文章

Camera调试ISP TimeOut问题,会是什么原因

在MT6572平臺上面調試camera 遇到isp timeout 硬體訊號都正常&#xff01;這是一些LOG K_ISP ERR: Timeout: Clear(1), IrqStatus(0x00000080), WaitStatus(0x00000001), Timeout(2000) K_ISP INF: 而我看MTK FAQ08102 裏這麼說 [FAQ08102][Camera Drv]Mt6572黑屏&#xff0c…

Linux网络编程2(理解局域网)

前面的一篇文章&#xff0c;我们简单地了解了网络的发展过程&#xff0c;并且简单的介绍了网络的一些基本术语&#xff0c;这篇文章&#xff0c;我们来详细的了解一下局域网的内容&#xff0c;相信看完这篇文章&#xff0c;大家能够对局域网有清晰的认识。 教科书一般是按照五层…

HCIA云计算实验-2-网络基础实验

HCIA云计算-02-网络基础实验 实验内容&#xff1a; 交换机视图介绍交换机基础配置VLAN原理实验路由原理实验 vlan 介绍 VLAN(Virtual Local Area Network)即虚拟局域网&#xff0c;是将一个物理的 LAN 在逻辑上划分成多个广播域的通信技术。每个 VLAN 是一个广播域&#xf…

平衡二叉树、B树、B+树、红黑树解析

目录 有序二叉树平衡二叉树构造平衡二叉树RRLLRLLR 平衡二叉树的优缺点&#xff1a; 2-3-4树红黑树B树B树B树、B树、红黑树的应用 有序二叉树 关于有序二叉树的详解以及 J a v a Java Java代码实现详见&#xff1a;二叉排序树详解并通过Java代码实现。每个节点最多有两个孩子…

为什么Qt源码中要用d_ptr和q_ptr

为什么需要d_ptr和q_ptr Qt中的公有类中一般都会包含d_ptr这样一个私有类型的指针&#xff0c;指针指向该类对应的私有类&#xff0c;引入这个指针主要是为了解决二进制兼容的问题。q_ptr是和d_ptr配套的&#xff0c;后面会介绍到。 什么是二进制兼容 Qt作为一个第三方库&…

【安卓】解析XML格式数据

这里需要搭建一个Web服务器&#xff0c;在这个服务器上提供一段XML文本&#xff0c;然后在程序里去访问这个服务器&#xff0c;再对得到的XML文本进行解析。首先需要下载一个Apache服务器的安装包&#xff0c;官方下载地址是&#xff1a;http://httpd.apache.org。然后一直点击…

OGR-矢量筛选

OGR-矢量筛选 1.属性筛选 # 根据字段属性进行过滤 ds ogr.Open(os.path.join(data_dir, global)) lyr ds.GetLayer(ne_50m_admin_0_countries) >1 lyr.SetAttributeFilter(continent "Asia") lyr.GetFeatureCount() >2:二次筛选 # You can still get a fe…

实训day34(8.22)

一、回顾 高并发集群 饿了么后端的登录模块 1、数据库 1. 主从复制(高可用) 2. 传统的主从复制 3. gtids事务型的主从复制 4. 注意 1. server_id唯一 2. 8.x版本需要get_ssl_pub_key 3. 5.x不需要 4. change master to 5. stop | start slave 5. 非交互 import pymys…