Chapter 1 Big O Notation
Chapter 1 Big O Notation
2015 1
What is an algorithm?
2015 2
Algorithms : An Algorithm is any well-defined
computational procedure that takes some value, or
set of values, as input and produces some value, or
set of values, as output.
An algorithm is thus a sequence of computational
steps that transform the input into the output.
We can also view an algorithm as a tool for solving a
well-specified computational problem.
For example, Sorting Problem
Input: A sequence of n numbers(a1, a2,….,an)
Output: A permutation (reordering) (a’1,a’2,….a’n) of
the input sequence such that a’1 <=,a’2 <=.a’n
For example, given the input sequence (31,
41,59,26,41,58), a sorting algorithm returns as
output the sequence (26, 31, 41, 41, 58, 59.)
An algorithm is said to be Correct if, for every input
instance, it halts with the correct output
2015 3
Properties of algorithms:
2015 4
Wewill use a pseudo code to specify
algorithms, which slightly reminds us of
C/C++/VB/Java and etc.
Example:an algorithm that finds the maximum
element in a finite sequence
2015 5
Another example: a linear search algorithm,
that is, an algorithm that linearly searches a
sequence for a particular element.
procedure linear_search(x: integer; a1, a2, …,
an: integers)
i := 1
while (i n and x ai)
i := i + 1
if i n then location := i
else location := 0
{location is the subscript of the term that
equals x, or is zero if x is not found}
2015 6
If
the terms in a sequence are ordered, a binary
search algorithm is more efficient than linear
search.
2015 7
binary search for the letter ‘j’
search interval
a c d f g h j l m o p r s u v x z
center element
2015 8
binary search for the letter ‘j’
search interval
a c d f g h j l m o p r s u v x z
center element
2015 9
binary search for the letter ‘j’
search interval
a c d f g h j l m o p r s u v x z
center element
2015 10
binary search for the letter ‘j’
search interval
a c d f g h j l m o p r s u v x z
center element
2015 11
binary search for the letter ‘j’
search interval
a c d f g h j l m o p r s u v x z
center element
found !
2015 12
The sequential search algorithm is very slow. If we
have an array of 1 million elements, we must do 1
million comparisons in the worst case.
2015 13
If
it is in the first half, we do not need to check
the second half. If it is in the second half, we do
not need to check the first half. In other words,
either ways we eliminate half the list from further
consideration. We repeat this process until we
find the target or satisfy ourselves that it is not in
the list.
2015 14
Basic idea: On each step, look at the middle
element of the remaining list to eliminate half
of it, and quickly zero in on the desired
element.
15 2015
Fir mi last Target =85
0 3 7
st d
Index 0 1 2 3 4 5 6 7
23 45 46 58 78 81 85 92
85 > 58
First mid lastTarget =85
4 5 7
Index 0 1 2 3 4 5 6 7
23 45 46 58 78 81 85 92
85 > 81
Firstmid lastTarget =85
6 6 7
Index 0 1 2 3 4 5 6 7
23 45 46 58 78 81 85 92
2015 16
if ( first > last)
return (-1);
mid=(first + last)/2;
if(x== a[mid]
return (mid);
if(x<a[mid])
search for x in a[first] to a[mid-
1];
else
search for x in a[mid+1] to
a[last];
2015 17
First last Target =85
0 3 7
0 1 2 3 4 5 6 7
23 45 46 58 78 81 85 92
85 > 58
Line 1: if (first > last) ? It is not true, so execute Line 3.
Line 3: Mid=(0+7)/2=3
2015 18
First mi lastTarget =85
4 5 7
d
0 1 2 3 4 5 6 7
23 45 46 58 78 81 85 92
2015 19
Fir mi lastTarget
6 6 7
st d =85
0 1 2 3 4 5 6 7
23 45 46 58 78 81 85 92
2015 20
Ingeneral, we are not so much interested in
the time and space complexity for small inputs.
2015 21
Forexample, let us assume two algorithms A
and B that solve the same class of problems.
The time complexity of A is 5,000n, the one
for B is 1.1n for an input with n elements.
For n = 10, A requires 50,000 steps, but B
only 3, so B seems to be superior to A.
Forn = 1000, however, A requires 5,000,000
steps, while B requires 2.51041 steps.
2015 22
This means that algorithm B cannot be used
for large inputs, while algorithm A is still
feasible.
2015 23
Comparison: time complexity of algorithms A
and B
2015 24
The growth of functions is usually described
using the big-O notation.
2015 25
When we analyze the growth of complexity
functions, f(x) and g(x) are always positive.
Therefore, we can simplify the big-O
requirement to
f(x) Cg(x) whenever x > k.
If
we want to show that f(x) is O(g(x)), we only
need to find one pair (C, k) (which is never
unique).
2015 26
Theidea behind the big-O notation is to
establish an upper boundary for the growth of a
function f(x) for large x.
Thisboundary is specified by a function g(x)
that is usually much simpler than f(x).
We accept the constant C in the requirement
f(x) Cg(x) whenever x > k,
because C does not grow with x.
We are only interested in large x, so it is OK if
f(x) > Cg(x) for x k.
2015 27
Example:
f(x) is O(x2).
2015 28
“Popular” functions g(n) are
n log n, 1, 2n, n2, n!, n, n3, log n
2015 29
A problem that can be solved with polynomial
worst-case complexity is called
tractable/Traceable.
2015 30
For any polynomial f(x) = anxn + an-1xn-1 + … +
a0, where a0, a1, …, an are real numbers,
f(x) is O(xn).
2015 31
What does the following algorithm compute?
procedure who_knows(a1, a2, …, an: integers)
m := 0
for i := 1 to n-1
for j := i + 1 to n
if |ai – aj| > m then m := |ai – aj|
{m is the maximum difference between any two
numbers in the input sequence}
Comparisons: n-1 + n-2 + n-3 + … + 1
= (n – 1)n/2 = 0.5n2 – 0.5n
Time complexity is O(n2).
2015 32
Another algorithm solving the same problem:
procedure max_diff(a1, a2, …, an: integers)
min := a1
max := a1
for i := 2 to n
if ai < min then min := ai
else if ai > max then max := ai
m := max - min
Comparisons: 2n - 2
2015 33
To simplify the running time estimation,for
a function f(n), we ignore the constants
and lower order terms.
3
2015 4
More Big-Oh Examples
7n-2
7n-2 is O(n)
need c > 0 and n0 1 such that 7n-2 c•n for n n0
this is true for c = 7 and n0 = 1
3n3 + 20n2 + 5
3n3 + 20n2 + 5 is O(n3)
need c > 0 and n0 1 such that 3n3 + 20n2 + 5 c•n3 for n n0
this is true for c = 4 and n0 = 21
3 log n + 5
3 log n + 5 is O(log n)
need c > 0 and n0 1 such that 3 log n + 5 c•log n for n n0
this is true for c = 8 and n0 = 2
3
2015 5
Growth Rate of Running Time
Consider a program with time complexity O(n2).
For the input of size n, it takes 5 seconds.
If the input size is doubled (2n), then it takes 20
seconds.
3
2015 7
In that algorithm, we have one loop
that processes all of the elements in
the array
Intuitively:
◦ If N was half of its value, we would expect the
algorithm to take half the time
◦ If N was twice its value, we would expect the
algorithm to take twice the time
That is true and we say that the
algorithm efficiency relative to N is
linear 2015
3
8
Let’s look at another algorithm for initializing the
values in a different array:
final int N = 500;
int [] [] counts = new int[N][N];
for (int i=0; i<counts.length; i++)
for (int j=0; j<counts[i].length; j++)
counts[i][j] = 0;
The length of time the algorithm takes to execute
still depends on the value of N
3
2015 9
However, in the second algorithm, we
have two nested loops to process the
elements in the two dimensional array
Intuitively:
◦ If N is half its value, we would expect the
algorithm to take one quarter the time
◦ If N is twice its value, we would expect the
algorithm to take quadruple the time
That is true and we say that the
algorithm efficiency relative to N is
quadratic
4
2015 0
We use a shorthand mathematical notation to
describe the efficiency of an algorithm relative to
any parameter n as its “Order” or Big-O
◦ We can say that the first algorithm is O(n)
◦ We can say that the second algorithm is O(n2)
For any algorithm that has a function g(n) of the
parameter n that describes its length of time to
execute, we can say the algorithm is O(g(n))
We only include the fastest growing term and
ignore any multiplying by or adding of constants
4
2015 1
Eight functions O(n) that occur
frequently in the analysis of
algorithms (in order of increasing rate
of growth relative to n):
◦ Constant 1
◦ Logarithmic log n
◦ Linear n
◦ Log Linear n log n
◦ Quadratic n2
◦ Cubic n3
◦ Exponential 2n
◦ Exhaustive Search n!
4
2015 2
n=1 n=2 n=4 n=8 n=16 n=32
1 1 1 1 1 1 1
logn 0 1 2 3 4 5
n 1 2 4 8 16 32
nlogn 0 2 8 24 64 160
n2 1 4 16 64 256 1024
n3 1 8 64 512 4096 32768
2n 2 4 16 256 65536 4294967296
n! 1 2 24 40320 20.9T Don’t ask!
4
2015 3
O(g(n)) for a problem means there is
some O(g(n)) algorithm that solves the
problem
Don’t assume that the specific algorithm
that you are currently using is the best
solution for the problem
There may be other correct algorithms
that grow at a smaller rate with
increasing n
Many times, the goal is to find an 4
2015 4
That brings up the topic of the structure of
the data on which the algorithm operates
If we are using an algorithm manually on
some amount of data, we intuitively try to
organize the data in a way that minimizes
the number of steps that we need to take
Publishers offer dictionaries with the words
listed in alphabetical order to minimize the
length of time it takes us to look up a word
4
2015 5
We can do the same thing for algorithms
in our computer programs
Example: Finding a numeric value in a
list
If we assume that the list is unordered,
we must search from the beginning to
the end
On average, we will search half the list
Worst case, we will search the entire list
Algorithm is O(n), where n is size of 4
2015 6
Find a match with value in an unordered list
int [] list = {7, 2, 9, 5, 6, 4};
4
2015 7
If we assume that the list is ordered, we can
still search the entire list from the beginning
to the end to determine if we have a match
But, we do not need to search that way
Because the values are in numerical order, we
can use a binary search algorithm
4
2015 8
Find a match with value in an ordered list
int [] list = {2, 4, 5, 6, 7, 9};
int min = 0, max = list.length-1;
while (min <= max) {
if (value == list[(min+max)/2])
statement; // found it
else
if (value < list[(min+max)/2])
max = (min+max)/2 - 1;
else
min = (min+max)/2 + 1;
}
statement; // didn’t find it
4
2015 9
The difference in the structure of the
data between an unordered list and an
ordered list can be used to reduce
algorithm Big-O
This is the role of data structures and
why we study them
We need to be as clever in organizing
our data efficiently as we are in figuring
out an algorithm for processing it
efficiently 5
2015 0
It may take more time to complete one
iteration of the second loop (due to more
code in the body of the loop), but the
growth rate of time taken with increasing
size of the array is less
As n gets large, the growth rate eventually
dominates the resulting time taken
That is why we ignore multiplication by or
addition of constants in Big-O notation
5
2015 1
Algorithm A Algorithm B
Run time: T = 20000N = O(N) T = 2N2 = O(N2)
■ Answer:
2015 52
Issue #2: Memory Limitations
■ Question: Which algorithm would you choose?
Algorithm A Algorithm B
Run time: O(N logN) O(N2)
Memory: O(N3) O(N)
■ Answer:
2015 53
■ Answer:
■ Itdepends how much time you have to write the program.
■ Another general rule in Computer Science is that the
faster the algorithm is, the more complicated it will be.
2015 54
Algorithm A Algorithm B
■ Answer:
2015 55
Suppose a program P is O(n3), and a
program Q is O(3n), and that currently
both can solve problems of size 50 in 1
hour. If the programs are run on
another system that executes exactly
729 times as fast as the original system,
what size problems will they be able
to solve?
2015 56
n3 = 503 * 729 n = 350 * 729
n = n = log3 (729 * 350)
3
503 * 3 729 n = log3(729) + log3 350
n = 50 * 9 n = 6 + log3 350
n = 50 * 9 = 450 n = 6 + 50 = 56
2015 57