Skip to content

Commit 0ad404a

Browse files
heikkitoivonenCopilot CLI
andcommitted
Fix: clarify substring search complexity — O(n+m) vs O(n*m)
Co-Authored-By: Copilot CLI <copilot-cli@example.invalid>
1 parent fe1d7a4 commit 0ad404a

7 files changed

Lines changed: 13 additions & 13 deletions

File tree

docs/builtins/bytes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ The `bytes` type is an immutable sequence of bytes, while `bytearray` is the mut
1616
| `copy()` | O(n) | Creates new bytes object |
1717
| `join()` | O(n) | Single pass, n = total output length |
1818
| `split()` | O(n) | Single pass |
19-
| `find(sub)` | O(n*m) | n = bytes length, m = pattern length |
19+
| `find(sub)` | O(n + m) worst for long strings, O(n*m) worst for pathological cases | n = bytes length, m = pattern length |
2020
| `replace(old, new)` | O(n) | Creates new bytes object |
2121
| `decode()` | O(n) | Convert to string |
2222
| `hex()` | O(n) | Convert to hex |
@@ -105,7 +105,7 @@ s = b.decode('ascii') # O(n)
105105
### Searching and Replacing
106106

107107
```python
108-
# Find substring: O(n*m)
108+
# Find substring: O(n + m) worst for long strings, O(n*m) worst for pathological cases
109109
data = b"hello world"
110110
idx = data.find(b"world") # O(n)
111111

docs/builtins/str.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ The `str` type is an immutable sequence of Unicode characters. Python strings ha
88
|-----------|------|-------|
99
| `len()` | O(1) | Direct lookup |
1010
| `access[i]` | O(1) | Direct indexing |
11-
| `in` (substring) | O(n*m) worst, O(n) avg | Uses fast skip algorithm in CPython |
12-
| `count(sub)` | O(n*m) worst | n = string, m = substring; uses fast algorithm |
13-
| `find(sub)` | O(n*m) worst, O(n) avg | Uses two-way or similar fast algorithm |
11+
| `in` (substring) | O(n + m) worst for long strings, O(n*m) worst for pathological cases | Uses Two-Way / fastsearch algorithm in CPython (linear worst-case) |
12+
| `count(sub)` | O(n + m) worst for long strings, O(n*m) worst for pathological cases | n = string, m = substring; uses Two-Way/fastsearch (linear worst-case) |
13+
| `find(sub)` | O(n + m) worst for long strings, O(n*m) worst for pathological cases | Uses Two-Way / fastsearch algorithm in CPython (linear worst-case) |
1414
| `replace(old, new)` | O(n) | Single pass |
1515
| `split(sep)` | O(n) | Single pass |
1616
| `join()` | O(n) | n = total chars |
@@ -80,8 +80,8 @@ result = "".join(str(i) for i in range(10000))
8080

8181
| Method | Complexity | Notes |
8282
|--------|-----------|-------|
83-
| `str.find()` | O(n*m) worst, O(n) avg | CPython uses two-way algorithm |
84-
| `str.count()` | O(n*m) worst, O(n) avg | Non-overlapping searches |
83+
| `str.find()` | O(n + m) worst for long strings, O(n*m) worst for pathological cases | CPython uses Two-Way / fastsearch algorithm (linear worst-case) |
84+
| `str.count()` | O(n + m) worst for long strings, O(n*m) worst for pathological cases | Non-overlapping searches (Two-Way/fastsearch) |
8585
| `str.replace()` | O(n) | Single pass with copy |
8686
| `str.split()` | O(n) | Single pass |
8787
| `str.startswith()` | O(m) | m = prefix length |

docs/implementations/cpython.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ gc.collect() # O(n) where n = tracked objects
113113

114114
| Operation | CPython Notes |
115115
|-----------|---|
116-
| `in` (substring) | O(n*m) worst, but highly optimized |
116+
| `in` (substring) | O(n + m) worst for long strings, O(n*m) worst for pathological cases |
117117
| `split()` | O(n) with specialized fast path |
118118
| `replace()` | O(n) with careful copying |
119119

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ See [Built-in Types](builtins/list.md) for detailed analysis.
4949

5050
## Why Trust This Documentation?
5151

52-
This documentation has been reviewed and refined through **100+ commits** by multiple AI coding agents (Amp, Claude, Antigravity, Kiro) working alongside human contributors. Each agent brings different perspectives and catches different issues, resulting in thorough cross-validation.
52+
This documentation has been reviewed and refined through **100+ commits** by multiple AI coding agents (Amp, Claude, Antigravity, Kiro, Copilot) working alongside human contributors. Each agent brings different perspectives and catches different issues, resulting in thorough cross-validation.
5353

5454
It's also **fully open source**—anyone can review the content, [file issues](https://github.com/heikkitoivonen/python-time-space-complexity/issues), or [submit improvements](https://github.com/heikkitoivonen/python-time-space-complexity/pulls). All sources are cited, and claims are based on official Python documentation and CPython source code.
5555

docs/versions/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ Python 3.13 → Python 3.14 Better GC pauses, new heapq functions
219219

220220
| Version | Lookup | Contains | Notes |
221221
|---------|--------|----------|-------|
222-
| 3.3+ | O(1) | O(n*m) | Flexible representation |
223-
| 3.11+ | O(1) | O(n*m)* | Faster due to inline caching |
222+
| 3.3+ | O(1) | O(n + m) worst for long strings, O(n*m) worst for pathological cases | Flexible representation |
223+
| 3.11+ | O(1) | O(n + m) worst for long strings, O(n*m) worst for pathological cases* | Faster due to inline caching |
224224

225225
## Upgrading Python
226226

docs/versions/py311.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ All standard complexities remain the same as Python 3.10:
8484
| list | insert | O(n) | Unchanged |
8585
| dict | lookup | O(1) avg | Unchanged |
8686
| set | add | O(1) amortized | Unchanged |
87-
| str | find | O(n*m) | Unchanged |
87+
| str | find | O(n + m) worst for long strings, O(n*m) worst for pathological cases | Unchanged |
8888

8989
*Amortized or average case, but faster in practice
9090

docs/versions/py39.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ All data structure complexities same as 3.8:
7676
| dict | lookup | O(1) avg |
7777
| dict | insert | O(1) avg |
7878
| set | add | O(1) amortized |
79-
| str | find | O(n*m) |
79+
| str | find | O(n + m) worst for long strings, O(n*m) worst for pathological cases |
8080

8181
## Data Structure Examples
8282

0 commit comments

Comments
 (0)