leetcode有效数字

简介: leetcode有效数字

公众号merlinsea


  • 题目要求判断一个字符串是否是一个合法的数,这个数可以是整数也可以是小数也可以带e/E表示科学计数法的数字。
  • 整数的要求: 整数可以是正整数,也可以是负整数。
  • 小数的要求:小数必须出现小数点,且小数点两边必须至少有一边出现数字,比如【.1】是合法的,【1.】也是合法的,【1.1】也是合法的,【.】是不合法的。
  • 带e/E的科学计数法的要求: e/E只能出现一次,e的前面可以是整数也可以是小数,e的后面必须是整数。比如【12e12】是合法,【12.2e-12】合法,【12.2e23.3】不合法因为e的后面必须是整数。
  • 以下都是合法的数:
    ["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]
  • 以下都是不合法的数:
    [["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]]


  • 解题思路:通过以上分析,可以把问题转为判断一个字符串是整数还是小数的问题。

640.png

java代码实现

/**
小数 [一定要有小数点]
1、可以有正负号[第一位]
2、点的左右至少出现一个数字
3、小数点有且仅有一个
整数 [不存在小数点]
1、可以有正负号
2、有数字 
e
1、e的后面必须出现整数[可以带正负号]
2、e的前面必须出现小数或整数(可以带胜负号)
3、e/E
 */
class Solution {
    public boolean isNumber(String s) {
        boolean r1 = isIntNumber(s);
        boolean r2 = isFloatNumber(s);
        boolean r3 = isENumber(s);
        return r1 || r2 || r3;
    }
    // 判断一个数字是否带e
    // 234E234.3
    private boolean isENumber(String s){
        int idx = -1; // 用于表示e的位置
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='e' || s.charAt(i)=='E'){
                if(idx!=-1){
                    // 说明出现了两个e
                    return false;
                }
                idx = i;
            }
        }
        if(idx == -1){
            // 说明没有e
            return false;
        }
        // 保证出现了e,并且只出现一次,idx
        String str1 = s.substring(0,idx); // 整数或者小数
        String str2 = s.substring(idx+1,s.length()); // 整数
        boolean r1 = isIntNumber(str1) || isFloatNumber(str1);
        boolean r2 = isIntNumber(str2);
        return r1 && r2;
    }
    // 判断一个数字是否是小数[]
    private boolean isFloatNumber(String s){
        if(s.length() == 0){
            return false;
        }
        boolean dot = false;
        boolean num = false;
        for(int i=0;i<s.length();i++){
            char ch = s.charAt(i);
            if(ch == '+' || ch == '-'){
                if(i!=0){
                    return false;
                }
            }else if(ch=='.'){
                if(dot){
                    return false;
                }
                dot = true;
            }else if(ch>='0' && ch<='9'){
                num = true;
            }else{
                return false;
            }
        }
        return dot && num;
    }
    // 判断一个数是否是整数 "+"
    private boolean isIntNumber(String s){
        if(s.length() == 0){
            return false;
        }
        boolean num = false;
        for(int i=0;i<s.length();i++){
            char ch = s.charAt(i);
            if(ch == '+' || ch == '-'){
                if(i!=0){
                    return false;
                }
            }else if(ch>='0' && ch<='9'){
                num = true;
            }else{
                return false;
            }
        }
        return num;
    }
}


java代码优化

class Solution {
    // 以e作为分割点,前半段可以是整数或者小数,后半段只能是整数
    // 数字【必须要出现】、小数点【只能出现一次】、正负号【只能出现一次,且在第一个】
    // E的条件 [只能出现一次,前面必须是整数或小数,后面必须是整数]
    public boolean isNumber(String s) {
        boolean sign = false; // 是否遇见了+-号
        boolean num = false; // 是否出现了数字
        boolean dot = false; // 是否出现了小数点
        boolean e = false; // 是否遇见了e
        for(int i=0;i<s.length();i++){
            char ch = s.charAt(i); 
            if(ch == '+' || ch=='-'){
                if(!sign){
                    if(i==0 || s.charAt(i-1)=='e' || s.charAt(i-1)=='E'){
                        // 出现了正负号且是第一个或者e后面的第一个
                        sign = true;
                    }else{
                        // 第一次出现了正负号但位置不对
                        return false;
                    }
                }else{
                    // 出现了多次正负号 
                    // 这里判断不了这个正负号是出现在e的两侧还是e的同一侧
                    return false;
                }
            }else if(ch == '.'){
                if(!dot){
                    // 说明第一次遇见小数点
                    dot = true;
                }else{
                    // 说明遇见了第二次小数点
                    return false;
                }
            }else if(ch>='0' && ch <='9'){
                num = true;
            }else if(ch == 'e' || ch =='E'){
                // -53.5 e -93
                if(!e && num){
                    // 说明e第一次出现并且前面出现了整数或者小数
                    e = true;
                    // e的后半段必须出现整数,为了方便判断后半部分必须是整数
                    sign = false; // e的后面可以出现正负号
                    num = false;
                    dot = true; // 虚拟点,占位
                }else{
                    // e出现了多次,或者前面没有出现数字
                    return false;
                }
            }else{
                return false;
            }
        }
        return num;
    }
}


c++代码实现

class Solution {
public:
    // 判断是否是一个小数、整数、带e/E
    bool isNumber(string s) {
        bool r1 = isIntNumber(s);
        bool r2 = isFloatNumber(s);
        bool r3 = isENumber(s);
        return r1 || r2 || r3;
    }
    // // 判断是否是一个小数、整数、带e/E,e只能出现一次
    bool isENumber(string s){
        if(s.size() == 0){
            return false;
        }
        int idx = -1;
        for(int i=0;i<s.size();i++){
            if(s[i]=='e' || s[i]=='E'){
                if(idx==-1){
                    idx = i;
                }else{
                    return false;
                }
            }
        }
        if(idx == -1){
            return false;
        }
       // [0,idx-1] , [idx+1,s.size()-1]
        string s1 = s.substr(0,idx);
        string s2 = s.substr(idx+1,s.size()-idx-1);
        bool r1 = isIntFloatNumber(s1);
        bool r2 = isIntNumber(s2);
        // 取交集
        return r1 && r2;
    }
    // 判断一个数字是否是整数/小数 , [合法的数]
    bool isIntFloatNumber(string s){
        bool isInt = isIntNumber(s);
        bool isFloat = isFloatNumber(s);
        return isFloat || isInt;
    }
    // 判断是否是小数 1.1   .1   1. 
    // 出现点 并且 出现了数字
    bool isFloatNumber(string s){
        if(s.size()==0){
            return false;
        }
        int i = 0;
        if(s[i]=='+'||s[i]=='-'){
            i++;
        }
        bool number = false;
        bool dot = false;
        while(i<s.size()){
            if(s[i]=='.'){
                if(!dot){
                    dot = true;
                }else{
                    //遇见了两次点
                    return false;
                }
            }else if(s[i]>='0' && s[i]<='9'){
                number = true;
            }else{
                return false;
            }
            i++;
        }
        return dot && number;
    }
    // 判断是否是整数 
    bool isIntNumber(string s){
        if(s.size()==0){
            return false;
        }
        int i = 0;
        if(s[i]=='+' || s[i]=='-'){
            i++;
        }
        // 假设s是一个整数 "+" --> return true;
        bool flag = false; // 表示是否出现了数字
        while(i<s.size()){
            if(s[i]>='0' && s[i]<='9'){
                flag = true;
                i++;
            }else{
                flag = false;
                break;
            }
        }
        return flag;
    }
};


c++代码优化

class Solution {
public:
    bool isNumber(string s) {
        bool sign = false; // 表示是否出现正负号
        bool e = false; //表示是否出现e
        bool dot = false; //表示是否出现小数点
        bool num = false; //表示是否出现数字
        int i = 0;
        while(i<s.size()){
            char ch = s[i];
            if(ch == '+' || ch == '-'){
                if(!e){
                    if(!num && !dot && !sign){
                        sign = true;
                    }else{
                        return false;
                    }
                }else{
                    if(!num && !sign){
                        sign = true;
                    }else{
                        return false;
                    }
                }
            }else if(ch == '.'){
                if(!dot){
                    dot = true;
                }else{
                    return false;
                }
            }else if(ch>='0' && ch<='9'){
                num = true;
            }else if(ch == 'e' || ch == 'E'){
                 //e只能出现一次,且e之前必须出现数字
                if(e || !num){
                    return false;
                }
                //重置结果,重新判断e之后的结果
                dot=true;
                num=false;
                sign=false;
                e=true;
            }else {
                return false;
            }
            i++;
        }
        return num;
    }
};

640.png

vip永久班算法直播教学,手把手带你刷leetcode,详情如下:

奔跑的小梁,公众号:梁霖编程工具库leetcode刷题永久班直播教学,手把手带你刷题,价格调整通知,2022年11月14日

相关文章
|
6月前
|
存储 SQL 算法
LeetCode 题目 65:有效数字(Valid Number)【python】
LeetCode 题目 65:有效数字(Valid Number)【python】
|
机器学习/深度学习 JavaScript
JS 刷 Leetcode:65. 有效数字
JS 刷 Leetcode:65. 有效数字
JS 刷 Leetcode:65. 有效数字
|
存储 C++
LeetCode 64最小路径和&65有效数字&66加一
简单的动态规划,只能向右或者向下,所以可以使用动态规划动态的找到最小路径和,先对第一行和第一列特殊处理,然后顺序遍历数组的时候状态转移方程为:
173 0
LeetCode 64最小路径和&65有效数字&66加一
|
机器学习/深度学习 算法 前端开发
「LeetCode」65-有效数字⚡️
「LeetCode」65-有效数字⚡️
127 0
「LeetCode」65-有效数字⚡️
☆打卡算法☆LeetCode 65、有效数字 算法解析
“给定一个字符串,判断是否是有效数字。”
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
61 6
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
123 2
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
40 1