We can consider this format:

`(^)(+/-)(xxx)(.)(xxx)(e)(+/-)(xxx)`

`-1***0****1***2***3***4***5****6`

Every `()`

means a phase, which starts from -1. `^`

means the beginning of the string, `xxx`

means digits. We can only move from a lower phase to a equal or higher phase.

Thus, `(^)`

is phase -1, if we are in this phase, it means we haven't scanned anything in the string yet.

Similarly, `(+/-)`

are phase 0 and phase 5. If we scan a `+`

or `-`

, we need to check which phase we are in. Only if we are in phase -1 or phase 4, can we proceed with the scanning (change the phase to 0 or 5, respectively), otherwise we return false.

`(xxx)`

are phase 1, 3, and 6. If we scan a digit, here are situations where we need to change our phase to 1, 3, or 6:

- we are in phase -1 or 0: change to phase 1
- we are in phase 2: change to phase 3
- we are in phase 4 or 5: change to 6

`(.)`

is phase 2. If we scan a dot and we are in phase -1, 0 or 1, we change the phase to 2, otherwise we return false.

`(e)`

is phase 4. If we scan a `e`

, here are situations where we proceed with the scanning (change the phase to 4):

- we are in phase 1
- we are in phase 3
- we are in phase 2 and there is at least a digit before the dot

otherwise we return false.

Finally, when we finished scanning, we know that we get a valid number if and only if we are in situations below:

- phase 1
- phase 2, and there is at least one digit before the dot
- phase 3
- phase 6

otherwise we return false.

```
public class Solution {
public boolean isNumber(String s) {
s = s.trim();
int phase = -1;
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if ('0' <= c && c <= '9') {
if (phase <= 0) phase = 1;
else if (phase == 2) phase = 3;
else if (phase == 4 || phase == 5) phase = 6;
} else if (c == '-' || c == '+') {
if (!(phase == -1 || phase == 4)) return false;
if (phase == -1) phase = 0;
if (phase == 4) phase = 5;
} else if (c == '.') {
if (!(phase <= 1)) return false;
phase = 2;
} else if (c == 'e') {
if (!(phase == 1 || phase == 3 || phase == 2 && i - 2 >= 0 && '0' <= s.charAt(i - 2) && s.charAt(i - 2) <= '9')) return false;
phase = 4;
} else return false;
}
if (phase == 1 || phase == 2 && s.length() > 1 && '0' <= s.charAt(s.length() - 2) && s.charAt(s.length() - 2) <= '9' || phase == 3 || phase == 6) return true;
else return false;
}
}
```