|
1 | | -# String Filter Conversion | 1 Line | O(d) | 1ms |
| 1 | +# String Replacement | 1 Line | O(d) | 1ms |
2 | 2 |
|
3 | 3 | # Intuition |
4 | | -We need to remove all '0' digits from the number's decimal representation. The most straightforward approach is to convert the number to a string, filter out '0' characters, and convert back to a number. |
| 4 | +We need to remove all occurrences of the digit '0' from a number. The simplest approach is to convert the number to a string, remove all '0' characters, and convert back to a number. |
5 | 5 |
|
6 | 6 | # Approach |
7 | | -**String Manipulation Pipeline:** |
8 | | -- Convert number to string to access individual digits |
9 | | -- Filter out all '0' characters |
10 | | -- Join remaining characters and convert back to number |
| 7 | +**String Manipulation with Regex:** |
| 8 | +- Convert number to string representation |
| 9 | +- Use regex to replace all '0' characters with empty string |
| 10 | +- Convert resulting string back to number |
11 | 11 |
|
12 | 12 | **Step-by-Step Process:** |
13 | 13 |
|
14 | 14 | 1. **Convert to String:** |
15 | | - - `n.toString()` converts the number to its string representation |
| 15 | + - `n.toString()` gives decimal string representation |
16 | 16 | - Example: 1020030 → "1020030" |
17 | | - - This allows character-level manipulation |
18 | 17 |
|
19 | | -2. **Split into Characters:** |
20 | | - - `.split('')` breaks the string into an array of individual characters |
21 | | - - Example: "1020030" → ['1','0','2','0','0','3','0'] |
22 | | - - Each digit becomes a separate element |
| 18 | +2. **Remove All Zeros:** |
| 19 | + - Use `replace(/0/g, '')` with regex |
| 20 | + - `/0/g` matches all '0' characters (g flag = global, all occurrences) |
| 21 | + - Replace with empty string effectively removes them |
| 22 | + - Example: "1020030" → "123" |
23 | 23 |
|
24 | | -3. **Filter Out Zeros:** |
25 | | - - `.filter((c) => c != '0')` keeps only non-zero characters |
26 | | - - Example: ['1','0','2','0','0','3','0'] → ['1','2','3'] |
27 | | - - Removes all '0' characters from the array |
28 | | - |
29 | | -4. **Join Back to String:** |
30 | | - - `.join('')` concatenates array elements back into a string |
31 | | - - Example: ['1','2','3'] → "123" |
32 | | - - Creates the final string without zeros |
33 | | - |
34 | | -5. **Convert to Number:** |
35 | | - - `Number(...)` parses the string back to an integer |
| 24 | +3. **Convert Back to Number:** |
| 25 | + - `Number()` or `parseInt()` converts string to integer |
36 | 26 | - Example: "123" → 123 |
37 | | - - Returns the numeric result |
| 27 | + - Automatically handles parsing without leading zeros |
38 | 28 |
|
39 | 29 | **Why This Works:** |
40 | 30 |
|
41 | | -**Correctness:** |
42 | | -- String operations preserve digit order |
43 | | -- Filter correctly identifies and removes all '0' characters |
44 | | -- Number conversion handles the result correctly |
| 31 | +**String Processing Benefits:** |
| 32 | +- Strings provide character-level access |
| 33 | +- Regex enables concise pattern matching |
| 34 | +- No need to handle digit extraction manually |
45 | 35 |
|
46 | | -**Simplicity:** |
47 | | -- Single-line solution using functional programming |
48 | | -- No manual loops or digit manipulation |
49 | | -- Built-in methods handle edge cases |
| 36 | +**Alternative Approaches:** |
50 | 37 |
|
51 | | -**Example Walkthrough (n = 1020030):** |
| 38 | +**Digit-by-Digit (Mathematical):** |
| 39 | +```typescript |
| 40 | +const removeZeros = (n: number): number => { |
| 41 | + let result = 0; |
| 42 | + let multiplier = 1; |
| 43 | + |
| 44 | + while (n > 0) { |
| 45 | + const digit = n % 10; |
| 46 | + if (digit !== 0) { |
| 47 | + result = digit * multiplier + result; |
| 48 | + multiplier *= 10; |
| 49 | + } |
| 50 | + n = Math.floor(n / 10); |
| 51 | + } |
| 52 | + |
| 53 | + return result; |
| 54 | +}; |
52 | 55 | ``` |
53 | | -1020030 |
54 | | - → "1020030" (toString) |
55 | | - → ['1','0','2','0','0','3','0'] (split) |
56 | | - → ['1','2','3'] (filter) |
57 | | - → "123" (join) |
58 | | - → 123 (Number) |
| 56 | +- More complex but avoids string conversion |
| 57 | +- O(d) time, O(1) space |
| 58 | +- Processes digits from right to left |
| 59 | + |
| 60 | +**Filter Array:** |
| 61 | +```typescript |
| 62 | +const removeZeros = (n: number): number => |
| 63 | + Number(n.toString().split('').filter(c => c !== '0').join('')); |
59 | 64 | ``` |
| 65 | +- More verbose than regex |
| 66 | +- Same complexity |
60 | 67 |
|
61 | | -**Edge Cases Handled:** |
| 68 | +**Example Walkthrough (n = 1020030):** |
62 | 69 |
|
63 | | -**No zeros:** |
64 | | -- Input: 123 |
65 | | -- Process: "123" → ['1','2','3'] → ['1','2','3'] → "123" → 123 |
66 | | -- Result: unchanged ✓ |
| 70 | +- toString(): "1020030" |
| 71 | +- replace(/0/g, ''): "123" |
| 72 | +- Number(): 123 |
| 73 | +- Result: 123 ✓ |
67 | 74 |
|
68 | | -**All zeros except one digit:** |
69 | | -- Input: 1000 |
70 | | -- Process: "1000" → ['1','0','0','0'] → ['1'] → "1" → 1 |
| 75 | +**Example 2 (n = 1):** |
| 76 | + |
| 77 | +- toString(): "1" |
| 78 | +- replace(/0/g, ''): "1" (no matches, unchanged) |
| 79 | +- Number(): 1 |
71 | 80 | - Result: 1 ✓ |
72 | 81 |
|
73 | | -**Single digit:** |
74 | | -- Input: 5 |
75 | | -- Process: "5" → ['5'] → ['5'] → "5" → 5 |
76 | | -- Result: 5 ✓ |
| 82 | +**Edge Cases:** |
| 83 | + |
| 84 | +**All zeros except one digit:** |
| 85 | +- Input: 10000 → Output: 1 |
| 86 | + |
| 87 | +**No zeros:** |
| 88 | +- Input: 12345 → Output: 12345 |
77 | 89 |
|
78 | 90 | **Leading zeros after removal:** |
79 | | -- Not possible since input is positive integer (no leading zeros in input) |
| 91 | +- Not possible as input is positive integer |
| 92 | +- String "0123" would become "123" → 123 |
80 | 93 |
|
81 | | -**Alternative Approaches:** |
| 94 | +**Single digit:** |
| 95 | +- 0: Technically not valid (positive integer constraint) |
| 96 | +- 5: Returns 5 |
82 | 97 |
|
83 | | -**Mathematical approach:** |
84 | | -```typescript |
85 | | -let result = 0; |
86 | | -let multiplier = 1; |
87 | | -while (n > 0) { |
88 | | - const digit = n % 10; |
89 | | - if (digit !== 0) { |
90 | | - result = digit * multiplier + result; |
91 | | - multiplier *= 10; |
92 | | - } |
93 | | - n = Math.floor(n / 10); |
94 | | -} |
95 | | -return result; |
96 | | -``` |
97 | | -- More complex, not more efficient |
98 | | -- Harder to read and maintain |
| 98 | +**Regex Explanation:** |
99 | 99 |
|
100 | | -**Regex approach:** |
101 | | -```typescript |
102 | | -return Number(n.toString().replace(/0/g, '')); |
103 | | -``` |
104 | | -- Similar performance |
105 | | -- Slightly less clear about "removing all instances" |
| 100 | +- `/0/` - Matches the character '0' |
| 101 | +- `/g` - Global flag: match all occurrences, not just first |
| 102 | +- Without `g`: "1020030".replace(/0/, '') → "120030" (only first '0' removed) |
| 103 | +- With `g`: "1020030".replace(/0/g, '') → "123" (all '0's removed) |
| 104 | + |
| 105 | +**Performance Considerations:** |
| 106 | + |
| 107 | +- String operations are generally O(d) where d is number of digits |
| 108 | +- For typical integers (up to 10^9), d ≤ 10 |
| 109 | +- String approach is simple and performant enough |
| 110 | +- Mathematical approach has O(1) space but more complex logic |
| 111 | + |
| 112 | +**Why Not Other Methods:** |
106 | 113 |
|
107 | | -**Why String Approach is Best:** |
108 | | -- Most readable and concise |
109 | | -- Leverages high-level built-in methods |
110 | | -- Performance is adequate for this problem |
111 | | -- Easy to understand and maintain |
| 114 | +- Splitting to array then filtering: More overhead than regex |
| 115 | +- Multiple passes: Regex is single pass |
| 116 | +- Recursive approach: Unnecessary complexity |
112 | 117 |
|
113 | 118 | # Complexity |
114 | | -- Time complexity: $$O(d)$$ where d is the number of digits - each digit processed once through filter |
115 | | -- Space complexity: $$O(d)$$ for temporary string and array storage |
| 119 | +- Time complexity: $$O(d)$$ where d is the number of digits in n |
| 120 | +- Space complexity: $$O(d)$$ for string representation |
116 | 121 |
|
117 | 122 | # Code |
118 | 123 | ```typescript |
119 | | -const removeZeros = (n: number): number => Number(n.toString().split('').filter((c) => c != '0').join('')); |
| 124 | +const removeZeros = (n: number): number => Number(n.toString().replace(/0/g, '')); |
120 | 125 | ``` |
0 commit comments