Leetcode: Valid Number


 This question is asked a lot at Facebook. Here it is, and it has an extremely low acceptance submission rate around 15%, so this is an extremely difficult question. 

A valid numbers can be split into:

1. A decimal number or an integer

2. An 'e' or an 'E' followed by an integer. 


A decimal number can be split into: 

1. (Optional) A sign character (either '+' or '-')

2. One of the following formats: 

    At least one digit followed by dot '.'

    At least one digit followed by dot '.' followed by at least one digit. 

    A dot '.' followed by at least one digit. 


An integer can be split into 

1. A sign character

2. At Least one digit. 


Given a string s, return if s is a valid number.


Here are the examples: 

Example 1:


Input: s = "0"

Output: true

Example 2:


Input: s = "e"

Output: false

Example 3:


Input: s = "."

Output: false

Example 4:


Input: s = ".1"

Output: true

 


Constraints:


1 <= s.length <= 20

s consists of only English letters (both uppercase and lowercase), digits (0-9), plus '+', minus '-', or dot '.'.


And below I will enumerate the code to solve this type of problem. 

According to the user balint, we need the number to match some sort of regular expression. 


[-+]?(([0-9]+(.[0-9]*)?)|.[0-9]+)(e[-+]?[0-9]+)?.

The first part is obvious because we have a decimal place in the middle of the number or there can be a number before a decimal number, or none, either way works. 

You either get a +- which is an optional or a integer + "." + another integer.

The second part has an E value and see if there is a +- value and a number from 0 to 9. There is also a method to do this in Javascript. 

Here's the Java method: 

public boolean isNumber(String s) {

    s = s.trim();

    if(s.length() == 0) return false; 

    boolean eSeen = false;

    boolean dotSeen = false;

    boolean numSeen = false;

    for(int i = 0; i < s.length(); i++) {

        char curr = s.charAt(i); 

        //first check if there is a digit, to ensure a number has been seen

        if(Character.isDigit(curr)) {

            numSeen = true;

            continue;

        }

        switch(curr) {

            case 'e':

            case 'E':

                //there has to be a digit before an 'e' or an 'E' character. 

                if(eSeen || !numSeen) return false;

                if(i == s.length() - 1) return false; 

                eSeen = true;

                continue;

            //there should only be one dot and the e should be after the dot. 

            case '.' :

                if(dotSeen) return false;

                if(eSeen) return false; 

                dotSeen = true;

                continue:

            //either the character +- has to be in the beginning, or an e has to be after the character. 

            case '-':

            case '+':

                if(i  > 0 && s.charAt(i - 1) != 'e' &&  s.charAt(i - 1) != 'e') return false; 

                if(i == s.length() - 1) return false;

                continue;

            default:

                return false; 

        }    

    }

    //pass all the cases first in the for loop and then we find a number. 

    return numSeen;

}


and here's the method in Javascript: 

var isNumber = function(s) {

    //regular expression [-+]?(([0-9]+(.[0-9]*)?)|.[0-9]+)(e[-+]?[0-9]+)?.

    return /^[+-]?(\d+\.?|\d*\.\d+)(e[+-]?\d+)?$/i.test(s);

}


Comments

Popular Posts