big O
function sum_char_codes(n: string): number {
let sum = 0;
for (let i = 0; i < n.length; ++i) {
sum += n.charCodeAt(i);
}
return sum;
}
- This is
because the runtime scales with the input (which is of size n) because we drop constants because we only care about how it grows with the input. As you take it to infinity, the constants become irrelevant - there are cases where
is faster than N, if N is sufficiently small - big O notation is for considering the worst case scenario (upper bound)
- growth is with respect to input
- constants dropped
- usually measure worst case
function sum_char_codes(n: string): number {
let sum = 0;
for (let i = 0; i < n.length; ++i) {
for (let j = 0; j < n.length; ++j) {
sum += charCode;
}
}
return sum;
}
This is
- quicksort is an example of
- you go over n characters, then half it then search n characters again and half it...
- binary search trees are
- arrays are just contiguous memory spaces
- lists != arrays
- getting a value from an array is
(assuming you know the offset * width) - i.e. constant time
- arrays are fixed sizes; to grow it you need to reallocate it because when you initialize it you know its size
The two crystal ball problem
- given 2 balls that will break if dropped from high enough, determine where it will break
- you could start at 0 and linearly walk up to the point where it breaks
- but you have 2 balls so you can do better than O(n)
- try jumping sqrt(n) each time with the first ball until it breaks
- O(sqrt(n))
Bubble sort
- move largest number to end
- move second largest to second last
- ...continue
- move second largest to second last
- gauss: sum of numbers in range (1..=n) is n(n+1)/2
-
- O(n^2)