65. Valid Number
Valid Number
A valid number can be split up into these components (in order):
- A decimal number or an integer.
- (Optional) An
'e'
or'E'
, followed by an integer.
A decimal number can be split up into these components (in order):
- (Optional) A sign character (either
'+'
or'-'
). - One of the following formats:
- One or more digits, followed by a dot
'.'
. - One or more digits, followed by a dot
'.'
, followed by one or more digits. - A dot
'.'
, followed by one or more digits.
- One or more digits, followed by a dot
An integer can be split up into these components (in order):
- (Optional) A sign character (either
'+'
or'-'
). - One or more digits.
For example, all the following are valid numbers: ["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]
, while the following are not valid numbers: ["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]
.
Given a string s
, return true
if s
is a valid number.
Example 1:
Input: s = "0" Output: true
Example 2:
Input: s = "e" Output: false
Example 3:
Input: s = "." Output: false
Constraints:
1 <= s.length <= 20
s
consists of only English letters (both uppercase and lowercase), digits (0-9
), plus'+'
, minus'-'
, or dot'.'
.
- More than one exponent character ('e'/'E'), or seeing an 'e'/'E' when a number has not yet been seen.
- More than one sign, or a sign appearing after a decimal or number have been seen. This gets reset when passing an 'e'/'E'.
- More than one decimal, or a decimal appearing after an 'e'/'E' has been seen.
- Any other non-number character appearing.
- Reaching the end of S without an active number.
- Time Complexity: O(N) where N is the number of characters in S
- Space Complexity: O(1)
var isNumber = function(S) {
let exp = false, sign = false, num = false, dec = false
for (let c of S)
if (c >= '0' && c <= '9') num = true
else if (c === 'e' || c === 'E')
if (exp || !num) return false
else exp = true, sign = false, num = false, dec = false
else if (c === '+' || c === '-')
if (sign || num || dec) return false
else sign = true
else if (c === '.')
if (dec || exp) return false
else dec = true
else return false
return num
};
// If you insist on using built-in functions, use this: // One line in Javascript: var isNumberOneLine = function(s) { return !isNaN(s) && s.trim() !== ''; } // Otherwise, this question is about using state machine. // I don't take credit for this solution. // I just convert it into Javascript and add the time and space complexity analysis. /** * Solution from: https://leetcode.com/problems/valid-number/discuss/360781/Python-with-state-machine-36ms * Function checks if a string is a number string. * Time = O(n) because we iterate through the whole string and each time * we do O(1) operations. * Space = O(n) because at most we store the whole inputString of length n. * @param {string} s * @return {boolean} */ var isNumber = function(s) { const SM = new StateMachine(); // Trim trailing spaces // because including spaces makes the states become too complicated. const inputString = s.trim(); let state = 'start'; for (const char of inputString) { try { state = SM.states[state][SM.classify(char)]; } catch(error) { return false; } } return state === 'integer' || state === 'frac' || state === 'exp_int'; }; class StateMachine { constructor() { // States store all transitions: this.states = { 'start': {'sign':'int_sign', 'digit':'integer', 'dot':'point'}, 'int_sign': {'digit':'integer', 'dot':'point'}, 'integer': {'digit':'integer', 'dot':'frac', 'e':'exp'}, 'point': {'digit':'frac'}, 'frac': {'digit':'frac', 'e':'exp'}, 'exp': {'digit':'exp_int', 'sign':'exp_sign'}, 'exp_sign': {'digit':'exp_int'}, 'exp_int': {'digit':'exp_int'} } } /** * Helper method returns the class of a char. * @param {string} char * @returns {string} */ classify(char) { if (!isNaN(parseInt(char))) return 'digit'; if (char === '.') return 'dot'; if (char === '+' || char === '-') return 'sign'; if (char === 'e') return 'e'; // If doesn't hit any of the cases above: throw new Error(); } }
Approach) One Liner
var isNumber = function(s) { return (! isNaN(s) ) && ( s.trim() !== "" ) && (! s.includes("Infinity") ) };
That’s all folks! In this post, we solved LeetCode problem 65. Valid Number
I hope you have enjoyed this post. Feel free to share your thoughts on this.
You can find the complete source code on my GitHub repository. If you like what you learn. feel free to fork 🔪 and star ⭐ it.
In this blog, I have tried to collect & present the most important points to consider when improving Data structure and logic, feel free to add, edit, comment, or ask. For more information please reach me here
Happy coding!
Comments
Post a Comment