Skip to content

Commit 8c4d078

Browse files
committed
feat: add atoi problem
1 parent 304e6ec commit 8c4d078

File tree

7 files changed

+319
-1
lines changed

7 files changed

+319
-1
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"problem_name": "string_to_integer_atoi",
3+
"solution_class_name": "Solution",
4+
"problem_number": "8",
5+
"problem_title": "String to Integer (atoi)",
6+
"difficulty": "Medium",
7+
"topics": "String",
8+
"tags": ["grind-75"],
9+
"readme_description": "Implement the `my_atoi(string s)` function, which converts a string to a 32-bit signed integer.\n\nThe algorithm for `my_atoi(string s)` is as follows:\n\n1. **Whitespace**: Ignore any leading whitespace (` `).\n2. **Signedness**: Determine the sign by checking if the next character is `-` or `+`, assuming positivity if neither present.\n3. **Conversion**: Read the integer by skipping leading zeros until a non-digit character is encountered or the end of the string is reached. If no digits were read, then the result is 0.\n4. **Rounding**: If the integer is out of the 32-bit signed integer range `[-2^31, 2^31 - 1]`, then round the integer to remain in the range. Specifically, integers less than `-2^31` should be rounded to `-2^31`, and integers greater than `2^31 - 1` should be rounded to `2^31 - 1`.\n\nReturn the integer as the final result.",
10+
"readme_examples": [
11+
{
12+
"content": "```\nInput: s = \"42\"\nOutput: 42\n```\n**Explanation:**\n```\nThe underlined characters are what is read in and the caret is the current reader position.\nStep 1: \"42\" (no characters read because there is no leading whitespace)\n ^\nStep 2: \"42\" (no characters read because there is neither a '-' nor '+')\n ^\nStep 3: \"42\" (\"42\" is read in)\n ^\n```"
13+
},
14+
{
15+
"content": "```\nInput: s = \" -042\"\nOutput: -42\n```\n**Explanation:**\n```\nStep 1: \" -042\" (leading whitespace is read and ignored)\n ^\nStep 2: \" -042\" ('-' is read, so the result should be negative)\n ^\nStep 3: \" -042\" (\"042\" is read in, leading zeros ignored in the result)\n ^\n```"
16+
},
17+
{
18+
"content": "```\nInput: s = \"1337c0d3\"\nOutput: 1337\n```\n**Explanation:**\n```\nStep 1: \"1337c0d3\" (no characters read because there is no leading whitespace)\n ^\nStep 2: \"1337c0d3\" (no characters read because there is neither a '-' nor '+')\n ^\nStep 3: \"1337c0d3\" (\"1337\" is read in; reading stops because the next character is a non-digit)\n ^\n```"
19+
},
20+
{
21+
"content": "```\nInput: s = \"0-1\"\nOutput: 0\n```\n**Explanation:**\n```\nStep 1: \"0-1\" (no characters read because there is no leading whitespace)\n ^\nStep 2: \"0-1\" (no characters read because there is neither a '-' nor '+')\n ^\nStep 3: \"0-1\" (\"0\" is read in; reading stops because the next character is a non-digit)\n ^\n```"
22+
},
23+
{
24+
"content": "```\nInput: s = \"words and 987\"\nOutput: 0\n```\n**Explanation:** Reading stops at the first non-digit character 'w'."
25+
}
26+
],
27+
"readme_constraints": "- `0 <= s.length <= 200`\n- `s` consists of English letters (lower-case and upper-case), digits (0-9), ` `, `+`, `-`, and `.`.",
28+
"readme_additional": "",
29+
"solution_imports": "",
30+
"solution_methods": [
31+
{ "name": "my_atoi", "parameters": "s: str", "return_type": "int", "dummy_return": "0" }
32+
],
33+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
34+
"test_class_name": "StringToIntegerAtoi",
35+
"test_helper_methods": [
36+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
37+
],
38+
"test_methods": [
39+
{
40+
"name": "test_my_atoi",
41+
"parametrize": "s, expected",
42+
"parametrize_typed": "s: str, expected: int",
43+
"test_cases": "[('42', 42), (' -042', -42), ('1337c0d3', 1337), ('0-1', 0), ('words and 987', 0), ('', 0), (' ', 0), ('+1', 1), ('-1', -1), ('2147483647', 2147483647), ('-2147483648', -2147483648), ('2147483648', 2147483647), ('-2147483649', -2147483648)]",
44+
"body": "result = self.solution.my_atoi(s)\nassert result == expected"
45+
}
46+
],
47+
"playground_imports": "from solution import Solution",
48+
"playground_test_case": "# Example test case\ns = '42'\nexpected = 42",
49+
"playground_execution": "result = Solution().my_atoi(s)\nresult",
50+
"playground_assertion": "assert result == expected"
51+
}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VERSION = 3.13
2-
PROBLEM ?= implement_trie_prefix_tree
2+
PROBLEM ?= string_to_integer_atoi
33
FORCE ?= 0
44
COMMA := ,
55

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# String to Integer (atoi)
2+
3+
**Difficulty:** Medium
4+
**Topics:** String
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 8](https://leetcode.com/problems/string-to-integer-atoi/description/)
8+
9+
## Problem Description
10+
11+
Implement the `my_atoi(string s)` function, which converts a string to a 32-bit signed integer.
12+
13+
The algorithm for `my_atoi(string s)` is as follows:
14+
15+
1. **Whitespace**: Ignore any leading whitespace (` `).
16+
2. **Signedness**: Determine the sign by checking if the next character is `-` or `+`, assuming positivity if neither present.
17+
3. **Conversion**: Read the integer by skipping leading zeros until a non-digit character is encountered or the end of the string is reached. If no digits were read, then the result is 0.
18+
4. **Rounding**: If the integer is out of the 32-bit signed integer range `[-2^31, 2^31 - 1]`, then round the integer to remain in the range. Specifically, integers less than `-2^31` should be rounded to `-2^31`, and integers greater than `2^31 - 1` should be rounded to `2^31 - 1`.
19+
20+
Return the integer as the final result.
21+
22+
## Examples
23+
24+
### Example 1:
25+
26+
```
27+
Input: s = "42"
28+
Output: 42
29+
```
30+
31+
**Explanation:**
32+
33+
```
34+
The underlined characters are what is read in and the caret is the current reader position.
35+
Step 1: "42" (no characters read because there is no leading whitespace)
36+
^
37+
Step 2: "42" (no characters read because there is neither a '-' nor '+')
38+
^
39+
Step 3: "42" ("42" is read in)
40+
^
41+
```
42+
43+
### Example 2:
44+
45+
```
46+
Input: s = " -042"
47+
Output: -42
48+
```
49+
50+
**Explanation:**
51+
52+
```
53+
Step 1: " -042" (leading whitespace is read and ignored)
54+
^
55+
Step 2: " -042" ('-' is read, so the result should be negative)
56+
^
57+
Step 3: " -042" ("042" is read in, leading zeros ignored in the result)
58+
^
59+
```
60+
61+
### Example 3:
62+
63+
```
64+
Input: s = "1337c0d3"
65+
Output: 1337
66+
```
67+
68+
**Explanation:**
69+
70+
```
71+
Step 1: "1337c0d3" (no characters read because there is no leading whitespace)
72+
^
73+
Step 2: "1337c0d3" (no characters read because there is neither a '-' nor '+')
74+
^
75+
Step 3: "1337c0d3" ("1337" is read in; reading stops because the next character is a non-digit)
76+
^
77+
```
78+
79+
### Example 4:
80+
81+
```
82+
Input: s = "0-1"
83+
Output: 0
84+
```
85+
86+
**Explanation:**
87+
88+
```
89+
Step 1: "0-1" (no characters read because there is no leading whitespace)
90+
^
91+
Step 2: "0-1" (no characters read because there is neither a '-' nor '+')
92+
^
93+
Step 3: "0-1" ("0" is read in; reading stops because the next character is a non-digit)
94+
^
95+
```
96+
97+
### Example 5:
98+
99+
```
100+
Input: s = "words and 987"
101+
Output: 0
102+
```
103+
104+
**Explanation:** Reading stops at the first non-digit character 'w'.
105+
106+
## Constraints
107+
108+
- `0 <= s.length <= 200`
109+
- `s` consists of English letters (lower-case and upper-case), digits (0-9), ` `, `+`, `-`, and `.`.

leetcode/string_to_integer_atoi/__init__.py

Whitespace-only changes.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from solution import Solution"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": 2,
16+
"id": "setup",
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"# Example test case\n",
21+
"s = \"42\"\n",
22+
"expected = 42"
23+
]
24+
},
25+
{
26+
"cell_type": "code",
27+
"execution_count": 3,
28+
"id": "execute",
29+
"metadata": {},
30+
"outputs": [
31+
{
32+
"data": {
33+
"text/plain": [
34+
"42"
35+
]
36+
},
37+
"execution_count": 3,
38+
"metadata": {},
39+
"output_type": "execute_result"
40+
}
41+
],
42+
"source": [
43+
"result = Solution().my_atoi(s)\n",
44+
"result"
45+
]
46+
},
47+
{
48+
"cell_type": "code",
49+
"execution_count": 4,
50+
"id": "test",
51+
"metadata": {},
52+
"outputs": [],
53+
"source": [
54+
"assert result == expected"
55+
]
56+
}
57+
],
58+
"metadata": {
59+
"kernelspec": {
60+
"display_name": "leetcode-py-py3.13",
61+
"language": "python",
62+
"name": "python3"
63+
},
64+
"language_info": {
65+
"codemirror_mode": {
66+
"name": "ipython",
67+
"version": 3
68+
},
69+
"file_extension": ".py",
70+
"mimetype": "text/x-python",
71+
"name": "python",
72+
"nbconvert_exporter": "python",
73+
"pygments_lexer": "ipython3",
74+
"version": "3.13.7"
75+
}
76+
},
77+
"nbformat": 4,
78+
"nbformat_minor": 5
79+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution:
2+
# Time: O(n)
3+
# Space: O(1)
4+
def my_atoi(self, s: str) -> int:
5+
i = 0
6+
n = len(s)
7+
8+
# Skip whitespace
9+
while i < n and s[i] == " ":
10+
i += 1
11+
12+
if i == n:
13+
return 0
14+
15+
# Check sign
16+
sign = 1
17+
if s[i] in {"+", "-"}:
18+
sign = -1 if s[i] == "-" else 1
19+
i += 1
20+
21+
# Convert digits
22+
result = 0
23+
while i < n and s[i].isdigit():
24+
result = result * 10 + int(s[i])
25+
i += 1
26+
27+
result *= sign
28+
29+
# Clamp to 32-bit range
30+
return max(-(2**31), min(2**31 - 1, result))
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
3+
from leetcode_py.test_utils import logged_test
4+
5+
from .solution import Solution
6+
7+
8+
class TestStringToIntegerAtoi:
9+
def setup_method(self):
10+
self.solution = Solution()
11+
12+
@pytest.mark.parametrize(
13+
"s, expected",
14+
[
15+
("42", 42),
16+
(" -042", -42),
17+
("1337c0d3", 1337),
18+
("0-1", 0),
19+
("words and 987", 0),
20+
("", 0),
21+
(" ", 0),
22+
("+1", 1),
23+
("-1", -1),
24+
("2147483647", 2147483647),
25+
("-2147483648", -2147483648),
26+
("2147483648", 2147483647),
27+
("-2147483649", -2147483648),
28+
# Edge cases
29+
("+-12", 0),
30+
("-+12", 0),
31+
("++1", 0),
32+
("--1", 0),
33+
(" +0 123", 0),
34+
("0000000000012345678", 12345678),
35+
("-000000000000001", -1),
36+
(" +000", 0),
37+
("123-", 123),
38+
(" 13 5", 13),
39+
(".1", 0),
40+
("1a33", 1),
41+
(" -0012a42", -12),
42+
("21474836460", 2147483647),
43+
("-21474836480", -2147483648),
44+
],
45+
)
46+
@logged_test
47+
def test_my_atoi(self, s: str, expected: int):
48+
result = self.solution.my_atoi(s)
49+
assert result == expected

0 commit comments

Comments
 (0)