Problem#
Given a string s
containing an out-of-order English representation of digits 0-9
, return the digits in ascending order .
Examples#
Example 1:
1
2
Input: s = "owoztneoer"
Output: "012"
Example 2:
1
2
Input: s = "fviefuro"
Output: "45"
Constraints:
1 <= s.length <= 105
s[i]
is one of the characters ["e","g","f","i","h","o","n","s","r","u","t","w","v","x","z"]
.
s
is guaranteed to be valid.
Solution#
Method 1 – Unique Letter Counting#
Intuition#
Each digit word (“zero”, “one”, …, “nine”) contains at least one unique character that does not appear in any other digit word, or appears in a way that allows us to uniquely identify the digit. For example, ‘z’ only appears in “zero”, ‘w’ in “two”, ‘u’ in “four”, ‘x’ in “six”, and ‘g’ in “eight”. By counting these unique letters, we can determine the number of each digit. For digits that share letters, we subtract the counts of already identified digits to get the correct count.
Approach#
Count the frequency of each character in s
using a counter.
For digits with unique identifying letters (0, 2, 4, 6, 8), set their counts directly.
For other digits (1, 3, 5, 7, 9), subtract the counts of digits already identified that share letters.
Build the output string by concatenating each digit the number of times it appears, in order from 0 to 9.
Complexity#
⏰ Time complexity: O(n)
, where n
is the length of s
, since we count each character once and process a fixed number of digits.
🧺 Space complexity: O(1)
, since the counter and digit counts use a fixed amount of space.
Code#
Cpp
Go
Java
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public :
string originalDigits(string s) {
vector< int > counter(26 );
for (char c : s) ++ counter[c - 'a' ];
vector< int > cnt(10 );
cnt[0 ] = counter['z' - 'a' ];
cnt[2 ] = counter['w' - 'a' ];
cnt[4 ] = counter['u' - 'a' ];
cnt[6 ] = counter['x' - 'a' ];
cnt[8 ] = counter['g' - 'a' ];
cnt[3 ] = counter['h' - 'a' ] - cnt[8 ];
cnt[5 ] = counter['f' - 'a' ] - cnt[4 ];
cnt[7 ] = counter['s' - 'a' ] - cnt[6 ];
cnt[1 ] = counter['o' - 'a' ] - cnt[0 ] - cnt[2 ] - cnt[4 ];
cnt[9 ] = counter['i' - 'a' ] - cnt[5 ] - cnt[6 ] - cnt[8 ];
string ans;
for (int i = 0 ; i < 10 ; ++ i)
for (int j = 0 ; j < cnt[i]; ++ j)
ans += char (i + '0' );
return ans;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func originalDigits (s string ) string {
counter := make([]int , 26 )
for _ , c := range s {
counter [c - 'a' ]++
}
cnt := make([]int , 10 )
cnt [0 ] = counter ['z' - 'a' ]
cnt [2 ] = counter ['w' - 'a' ]
cnt [4 ] = counter ['u' - 'a' ]
cnt [6 ] = counter ['x' - 'a' ]
cnt [8 ] = counter ['g' - 'a' ]
cnt [3 ] = counter ['h' - 'a' ] - cnt [8 ]
cnt [5 ] = counter ['f' - 'a' ] - cnt [4 ]
cnt [7 ] = counter ['s' - 'a' ] - cnt [6 ]
cnt [1 ] = counter ['o' - 'a' ] - cnt [0 ] - cnt [2 ] - cnt [4 ]
cnt [9 ] = counter ['i' - 'a' ] - cnt [5 ] - cnt [6 ] - cnt [8 ]
ans := []byte {}
for i , c := range cnt {
ans = append(ans , bytes .Repeat ([]byte {byte('0' + i )}, c )... )
}
return string(ans )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public String originalDigits (String s) {
int [] counter = new int [ 26] ;
for (char c : s.toCharArray ()) {
++ counter[ c - 'a' ] ;
}
int [] cnt = new int [ 10] ;
cnt[ 0] = counter[ 'z' - 'a' ] ;
cnt[ 2] = counter[ 'w' - 'a' ] ;
cnt[ 4] = counter[ 'u' - 'a' ] ;
cnt[ 6] = counter[ 'x' - 'a' ] ;
cnt[ 8] = counter[ 'g' - 'a' ] ;
cnt[ 3] = counter[ 'h' - 'a' ] - cnt[ 8] ;
cnt[ 5] = counter[ 'f' - 'a' ] - cnt[ 4] ;
cnt[ 7] = counter[ 's' - 'a' ] - cnt[ 6] ;
cnt[ 1] = counter[ 'o' - 'a' ] - cnt[ 0] - cnt[ 2] - cnt[ 4] ;
cnt[ 9] = counter[ 'i' - 'a' ] - cnt[ 5] - cnt[ 6] - cnt[ 8] ;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; ++ i) {
for (int j = 0; j < cnt[ i] ; ++ j) {
sb.append (i);
}
}
return sb.toString ();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from collections import Counter
class Solution :
def originalDigits (self, s: str) -> str:
counter = Counter(s)
cnt = [0 ] * 10
cnt[0 ] = counter['z' ]
cnt[2 ] = counter['w' ]
cnt[4 ] = counter['u' ]
cnt[6 ] = counter['x' ]
cnt[8 ] = counter['g' ]
cnt[3 ] = counter['h' ] - cnt[8 ]
cnt[5 ] = counter['f' ] - cnt[4 ]
cnt[7 ] = counter['s' ] - cnt[6 ]
cnt[1 ] = counter['o' ] - cnt[0 ] - cnt[2 ] - cnt[4 ]
cnt[9 ] = counter['i' ] - cnt[5 ] - cnt[6 ] - cnt[8 ]
ans = []
for i in range(10 ):
ans. append(str(i) * cnt[i])
return '' . join(ans)