My simple 4ms Java solution with A VERY detailed explanation


  • 2
    F

    It’s not really difficult as a problem. Using the ascii code, we can check if a character is numerical or not in just one line. The difficult part here to deal with the different “special characters” which can be in the string like ‘+’, ‘-‘, ‘.’ and ‘e’. My solution is to know EXACTLY in which place a special character can be.

    1. First, the obvious special character is the white spaces. We will iterate in the string with two indexes (start and end) to ignore the white spaces at the beginning and at the end of the string. Use methods like trim or substring is LIKE cheating. In pure algorithm, we had to use indexes (and it's not difficult).

    2. Then, come our first special characters: + and -. The idea is to see they can be present only in two scenarios : at the beginning of the string (ex : “+2” or “-2”) or at the middle if they are preceded by ‘e’, when we want to express the power of 10 in a number. (ex : “2e3” or “2e-4). So, the easier case is to check first if they are present at the beginning. For the other case, we will check for it later.

    3. Now, we will iterate at the string. We will use two counters for the position of ‘.' and e in the string (it’s of course the hardest part) :

    • We can eliminate some obvious cases : ALL these special characters can only be present one time in a string. In particular, if we met ‘.' and e more than once, we return false.

    • We will consider the possible position of e in a string. In opposite of ‘.’, e CAN'T be at the beginning or at the end of the string, it can be only at the middle. So, we will return false if we met e at these bounds including the cases like “+e2” or “-e3” (we had used the flag for “+” or “-“ to know the real start of the number).

    • Now, we had to get benefit from the “meaning” of e, it express the power of 10 in a number. Consequently, the number after e has to be integer (don’t contain any ‘.’) AND the part before ‘e’ has to be a valid number. It means that we can’t have just point before ‘e’. For example : ‘.e3 ‘ is not valid. It means that ‘e’ and ‘.’ can’t be successive.

    • Finally, we will check for a non numerical character. If we met a non numerical character we will return false except if we met ‘+’ or ‘-‘ (which can ALSO be at the middle). In that case, we will verify if they are preceded by e and followed by at least one digit.

    That's it for the theoretical part. In programming, some optimisations can be done (you can always improve my code), the code below contains comments to explain in details all the steps :

    public static boolean isNumber(String str){
    	if ( str == null || str.isEmpty() ) return false;
    	
    	int start = 0;
    	int end  = str.length() - 1;
    	
    	//1st step : remove spaces
    	while (start < str.length()-1 &&  str.charAt(start) == ' ')
    		start ++;
    			
    	while (end >= start +1 &&  str.charAt(end) == ' ')
    		end --;
    	
    	//2nd step : check when the string has only one char
    	if( (start - end ==0) &&  (str.charAt(start) < '0' || str.charAt(start) > '9') )
    		return false;   //string of only one non numerical char
    	
    	//3rd step : check for '+' and '-' when they are at the beginning of the string
    	if (str.charAt(start)== '+' || str.charAt(start)== '-') {
    		if (str.charAt(start+1) == '.' && (end - start == 1))
    			return false;
    		start++;
    	}
    	
    	int point = -1;   //position of '.' in the string
    	int e = -1;       //position of 'e' in the string
    	
                //4th step : check for all the remaining cases
    	for (int i = start; i <=end; i++){
    		
    		if (str.charAt(i) == '.') {
    			if (point == -1)  //if we met the point for the FIRST time, we store its position
    				point = i;   //a string that has TWO point can't be a valid number
    			else return false;
    		}
    		
    		if (str.charAt(i) == 'e')  {
    			if (e==-1)     //same raisoning for e
    				e= i;
    			else return false;
    		}
    		
    		if (e == start || e==end) return false; //e has to be at the middle
    		if (point > e && e!= -1 ) return false; //the part AFTER e must be only integer
    		if (point == start && e== start +1) return false; //the part BEFORE e must be a valid number
    		
    		//if we met a non numerical digit
    		if ( (str.charAt(i) < '0' || str.charAt(i) > '9')  && str.charAt(i) !='.' && str.charAt(i) != 'e' ) {
    
    		        //we met + or - at the middle but in a correct configuration. So, we continue
    			if (  (str.charAt(i) == '+' || str.charAt(i) == '-')  && e== i-1 && i!=end ) {  }
    	
    			else 	return false;
    		}
    	}
    	return true;
    }

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.