1. Dynamic Array with Linear Scan
Intuition
Use an array/list of integers:
- insert(val): Check if val exists in O(n) time and append it to the end in O(1).
- remove(val): Search for the first occurrence of val in O(n) time, then shift subsequent elements or swap with the last element to remove in O(n) or O(1).
- getRandom(): Select a random index 0 <= idx < size in O(1).
While simple, the linear scan causes operations to take O(n) time worst case.
When to apply: Prototyping or when total operations are very small.
Algorithm
- Step 1: Maintain a single dynamic array list.
- Step 2: On insert(val), scan to check whether val was already present, then append val.
- Step 3: On remove(val), scan for the first occurrence of val. If found, remove it and return true; else return false.
- Step 4: On getRandom(), pick a random index between 0 and list.size() - 1.
#include <iostream>#include <vector>#include <cstdlib>#include <algorithm> class RandomizedCollectionBrute { std::vector<int> nums;public: RandomizedCollectionBrute() {} bool insert(int val) { bool notPresent = (std::find(nums.begin(), nums.end(), val) == nums.end()); nums.push_back(val); return notPresent; } bool remove(int val) { auto it = std::find(nums.begin(), nums.end(), val); if (it == nums.end()) return false; nums.erase(it); return true; } int getRandom() { return nums[rand() % nums.size()]; }}; int main() { RandomizedCollectionBrute rc; std::cout << (rc.insert(1) ? "true" : "false") << std::endl; std::cout << (rc.insert(1) ? "true" : "false") << std::endl; std::cout << (rc.insert(2) ? "true" : "false") << std::endl; std::cout << rc.getRandom() << std::endl; std::cout << (rc.remove(1) ? "true" : "false") << std::endl; std::cout << rc.getRandom() << std::endl; return 0;}Time & Space Complexity
- Time complexity:
O(n) for insert and remove, O(1) for getRandom - Space complexity:
O(n) for storing items