1. Dynamic Array Storage with Full Scan
Intuition
Append words into vector<string>. For search(word), check if w == word. For startsWith(prefix), check if w.find(prefix) == 0. Scans up to N words each time.
When to apply: Toy implementation for small test cases.
Algorithm
- Step 1: Maintain list of words.
- Step 2:
insert: add to list. - Step 3:
search: linear scan for exact match. - Step 4:
startsWith: linear scan for prefix match.
#include <iostream>#include <string>#include <vector>using namespace std; class Trie { vector<string> dict;public: Trie() {} void insert(string word) { dict.push_back(word); } bool search(string word) { for (const string& w : dict) { if (w == word) return true; } return false; } bool startsWith(string prefix) { for (const string& w : dict) { if (w.rfind(prefix, 0) == 0) return true; } return false; }}; int main() { Trie trie; trie.insert("apple"); cout << "search('apple'): " << (trie.search("apple") ? "true" : "false") << endl; cout << "search('app'): " << (trie.search("app") ? "true" : "false") << endl; cout << "startsWith('app'): " << (trie.startsWith("app") ? "true" : "false") << endl; return 0;}Time & Space Complexity
- Time complexity:
insert: O(1), search: O(N * L), startsWith: O(N * L)— Must inspect every word in the list for search and prefix queries. - Space complexity:
O(N * L)— Stores all N words in memory.
Why Brute Force Doesn't Scale:
With 30,000 words and 30,000 queries, brute force executes 9 * 108 string operations.
A 26-ary Trie answers each query in exactly L pointer dereferences (e.g., <= 10 steps), running in sub-milliseconds.