CPSC 413 Lecture Notes - Part I Department of Computer Science
CPSC 413 Lecture Notes - Part I Department of Computer Science
Fall, 1998
2
Contents
I Introduction 7
3
5 Sample Tests 59
5.1 Class Test for 1996 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.2 Class Test for 1997 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6 Asymptotic Notation 63
6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.2 Worst Case Running Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.3 Asymptotically Positive Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
6.4 Big-Oh Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.5 Big-Omega Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.6 Big-Theta Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.7 Little-Oh Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.8 Some “Rules of Thumb” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.9 Application to the Analysis of Algorithms . . . . . . . . . . . . . . . . . . . . . . . . 76
6.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.11 Hints for Selected Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
6.12 Sample Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7 Summations 83
7.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.2 A Motivating Example and a Cost Measure . . . . . . . . . . . . . . . . . . . . . . . 83
7.3 Expressions in Closed Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.4 Recognition of Special Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.5 Completing and Confirming a Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.6 Applying Linear Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
7.7 Bounding Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
7.8 Splitting the Sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
7.9 Approximation of Sums by Integrals . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
7.10 Completing and Confirming a Pattern, Continued . . . . . . . . . . . . . . . . . . . . 99
7.11 Analysis of Nonrecursive Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
7.12 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
7.13 Hints for Selected Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
7.14 Sample Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8 Recurrences 109
8.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8.2 Motivating Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8.3 Recurrences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
8.4 Methods for Solving Recurrences: The Substitution Method . . . . . . . . . . . . . . 113
8.5 The Iteration Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
8.6 Simplifying the Problem by (Correctly) Modifying the Recurrence . . . . . . . . . . 124
8.7 The Master Theorem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.8 Solving Linear Recurrences with Constant Coefficients . . . . . . . . . . . . . . . . . 140
8.9 An Additional Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
8.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4
8.11 Hints for Selected Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
8.12 Sample Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Bibliography 234
Index 236
5
6
Part I
Introduction
7
Chapter 1
1.1 Overview
This chapter provides an introduction to the course. First, “two motivating problems” are defined
and used to raise issues that will be considered throughout CPSC 413. This is followed by a longer
description of the course, including an explanation of why the course is required for a BSc in
Computer Science and what it is hoped that students will learn by taking it. Later sections include
descriptions of other resources that are available to CPSC 413 students and suggestions of things
to do in order to increase the likelihood that you’ll do well in this course.
2. Integer Primality takes a positive integer n ≥ 2 as input and returns the answer “Yes” if n is
prime, or “No” if n is composite.
These problems are both “computable,” as this was defined in CPSC 313: You could decide on
reasonable encodings for inputs and outputs and then write Turing machine programs for each. As
far as CPSC 313 is concerned, the problems are therefore “easy” in this sense.
However, from the perspective of CPSC 413 (which analyses algorithms and introduces the
theory of computational complexity), these problems are quite different.
1.2.2 Representations
Of course, in order to define these problems completely enough to solve them, it’s necessary to
agree on a way to represent the problem’s inputs and outputs. As in CPSC 313, we’ll represent
both as strings over some finite alphabet.
Several representations of the input (an integer n) are possible. Here are two:
9
2. A “decimal” representation, using an alphabet that includes the digits from 0 to 9 as well as a
terminator symbol, such as a blank. An integer n would be given by its decimal representation,
which has length approximately log10 n.
From the perspective of CPSC 313 these two representation schemes are pretty much the same,
in the sense that it’s easy to convert from either one to the other using a deterministic Turing
machine (or random access machine, etc).
From the perspective of CPSC 413, these two representations are completely different: The
length of the first representation of n is exponential in the length of the second representation of n,
so that the first representation scheme is “unacceptable” (while the second is perfectly OK).
This second representation is unacceptable because it’s so much longer than the first. It’s
entirely possible that there’s an algorithm to solve each problem using the first representation,
when given some value n as input, in far less time than you’d need just to read the same input
value n if the second representation had been used instead!
In CPSC 413, we won’t always insist that the shortest possible representation of an input be
used — but we’ll definitely reject representations that are exponentially longer than necessary.
In particular, a binary representation of n, hexadecimal representation of n, or a representation
using another base (provided that the base is greater than or equal to two), will also be acceptable
for the purposes of CPSC 413: You can convert from any of these representations of n to a decimal
representation, or vice-versa, deterministically in polynomial-time, and the length of any one of
these representations of n is linear in the length of any of the others.
Now, representing outputs will be straightforward. Since the output of Integer Squaring is just
another integer, we’ll agree to use the same representation of outputs as for inputs in this case. The
output of Integer Primality is always either “Yes” or “No;” we’ll agree that “Yes” is represented
by the symbol “1” and “No” by “0”
10
check whether the integer
n = 3, 558, 458, 718, 976, 746, 753, 830, 538, 032, 062, 222, 085, 722, 974, 125, 723
is prime — but if you write a computer program to do this, make sure you have a way to stop it
before it completes!
Let’s assume that you wrote such a program (and that you didn’t “cheat” by changing the
algorithm that’s been described). No current computer is able to perform anything close to one
trillion (1012 ) integer operations per second — and it isn’t likely that computers will be able to
operate this quickly any time soon — so let’s be generous and assume that this is the number
of operations that can be performed. Since n is “probably prime” (according to the computer
algebra system Maple), the number of these operations that will be executed by this algorithm is
√
“probably” approximately n/2 — and you’d need just under thirty thousand years in order
to complete this many operations, using the above estimate of the number of operations that can
be performed per second. (Since the estimate isn’t accurate, this amount of time might not be
enough!)
Note that the number of digits you need to write n (that is, the size of the input) is less than
fifty.
11
sufficiently many large primes, so that you won’t have to look too long before a prime number is
found — provided that your “random number generator” is reliable.
Professor Cleve is the person in the department whose research areas include cryptography, so
you should ask him about this if you’re interested!
Asymptotic Performance
General interest in asymptotic performance began in the 1960’s and 1970’s, when computers had
been available long enough to be used for large scientific and engineering problems, but before they
were quite as powerful or widely available as today.
At around that time, computers were being used to solve larger problems than had been attacked
before, and it began to be clear that some of the methods that had been good enough to solve
small problems by hand didn’t scale up — they were either using far too much time or far too
much space on larger inputs to be useful, so that new “asymptotically efficient” techniques would
be needed to deal with the larger problems that were of interest.
Another trend was becoming evident: While computers were becoming more powerful, and
more widely available, the demand for computing was also growing. It wasn’t just true that the
number of problems to be solved was growing; the size of the problems (seen to be of interest) was
growing too.
Because of this, difficulties caused by the lack of asymptotically efficient solutions for some
problems didn’t decrease over time — they tended to increase, instead!
Comparison of Algorithms
These days it’s clear that there are other things that a developer should worry about besides the
efficiency of a program. Indeed, there are quite a few other things that should often to be considered
to be more important — including correctness, ease of use, and maintainability.
However, it is still the case that asymptotic performance is important in some application areas,
including scientific and engineering computations. And, more generally, when other important
requirements are satisfied, it’s still reasonable to prefer a program that’s efficient to one that isn’t.
It’s also true that there are other ways, besides performing a mathematical analysis, to assess
the performance of an algorithm: You can also write the source code, and compile and profile it,
and you can perform other kinds of experiments or tests as well.
A mathematical analysis can’t really replace this kind of experimentation, because profiling
and similar testing frequently reveal more about how a program will run on a particular platform,
12
and when the system is under a particular load, than you can easily discover using a mathematical
analysis.
On the other hand, experimentation can’t replace mathematical analysis, either: There’s no
way to perform a finite number of experiments in order to measure an algorithm’s performance on
an infinite number of arbitrarily large inputs.
So, it’s (still) true that at a minimum, a software developer should know enough about the
asymptotic performance and analysis of algorithms to be able to make an intelligent choice
between algorithms or programs, based on their asymptotic performance. This includes
the ability to compare two asymptotic performance bounds, in order to decide which is
better, and to take source code and derive an accurate asymptotic performance bound
for it.
By the way, it’s reasonably common to find “asymptotic performance bounds” associated with
algorithms or programs when these are published in conference papers or journal articles. It isn’t
quite as common to find this kind of performance guarantee associated with software that’s part
of a component library for a programming language or environment. This may be changing: The
Standard Template Library is an example of such a component library for which these guarantees
are given. This library has been included in the ANSI/ISO C++ draft standard, so it should
eventually be widely known and used. And, it’s to be expected that this kind of asymptotic
performance guarantee will be provided for future libraries as well, now that this precedent has
been set.
Design of Algorithms
A developer who’s been in the business for a few years and is advancing through the ranks will be
expected to do much more than produce source code based on a design that’s been handed to him,
or to develop software by choosing from “off the shelf” components.
Such a person might not be directly involved with software development at all — for example,
he (or she) might be managing software development instead.
On the other hand, she (or he) might now be expected to design new solutions for problems.
This might include developing new algorithms rather than using old ones. If performance on
large inputs is a concern then she or he will need to know something about techniques that can be
used to avoid things like “brute force” or “exhaustive” searches — techniques that are useful for
designing algorithms that are asymptotically efficient (so that they scale up well).
Complexity Theory
Unfortunately, these techniques won’t always be good enough — sometimes, because our knowledge
of algorithm analysis and design is incomplete, but (worse yet) sometimes because a problem doesn’t
have an asymptotically efficient solution at all.
If you’ve taken CPSC 313 then you should know about some problems that are provably unde-
cidable, so that it’s provably impossible to solve them reliably by computer (on arbitrary inputs).
There is another class of problems that are decidable but that are also known to be intractable,
so that they have no asymptotically efficient solutions.
There’s also a much larger class of problems that are widely believed to be intractable and whose
complexity has been proved to be related, so that if any one of them has an efficient solution then
they all do.
Many of the problems that are provably undecidable, or provably intractable, seem to be quite
artificial (though this certainly isn’t always the case) — that is, they’re only of interest because
13
of the properties they can be proved to possess, and not because very many people would ever
be interested in solving them. Others are only encountered if you’re trying to use a computer to
analyze other computer programs.
Unfortunately, quite a few of the problems that are “widely believed” to be intractable (and
whose complexities are related) are quite natural. These problems can be found in numerous
application areas, including network design, scheduling, and program optimization (as well as
computational number theory, algebra, and so on).
So it wouldn’t be surprising at all if a senior developer was asked to produce an efficient solution
for one of these problems.
Under the circumstances the developer almost certainly won’t be able to do this, and shouldn’t
spend much time trying.
On the other hand, he’ll want to keep his job.
So it’s appropriate for the developer to recognize the fact that it’s likely (or, sometimes, prov-
able) that the problem doesn’t have an asymptotically efficient solution; report this fact; and then
help to deal with this, by looking for a special case of the problem (or a slightly different problem)
that does have an efficient solution and can be used instead, or by identifying weaker performance
guarantees for the original problem that can be met and that are acceptable (or, by doing something
else along these lines). In order to do this much, the developer should know enough “complexity
theory” to realize what results in this area imply, and should recognize, or be able to
find, problems that are already known or widely believed to be intractable.
Unfortunately, this still might not be enough.
Computers are still being used in new application areas, so it’s still the case that a developer
might be asked to solve a problem that hasn’t been considered before. The problem might be
intractable, but this fact wouldn’t have been recognized yet, because the problem is new.
This problem might be completely different from any problems whose status is already known;
in this case, it might be quite difficult to show that it’s intractable. On the other hand, it might be
a somewhat “disguised” version of a problem that’s known to be intractable (or “widely believed
to be intractable”) already; in this case, the job of classifying the problem is generally easier.
Fortunately, this second case seems to be more common than the first.
Either way, the developer will want to “extend” our knowledge of complexity theory, by de-
termining the status of the new problem. This will often involve the use of standard techniques
for proving hardness (or “probable intractability”) of problems, especially if the second
(easier) case applies — but these techniques are quite different from just looking for the problem
in a list of problems that are known to be hard already.
• Techniques to compare asymptotic performance bounds, and to obtain these bounds from
source code. These mathematically-based techniques seem to be less interesting to many
students than the rest of the course material, so it’s unfortunate that this is the first material
that will be studied. However, it’s easier to assess the algorithms you design and prove results
about problems if you know something about algorithm analysis first. That is, the rest of the
course builds on this drier material, making it necessary to put it at the beginning.
• Some techniques to design algorithms that are asymptotically efficient — generally, ways to
avoid brute force searches.
14
• An introduction to an important part of complexity theory — the theory of NP -completeness.
This includes statements of some of the fundamental definitions and results in the area (useful
when you need to try to apply the theory, as you encounter problems that are already known
or widely believed to be intractable), and a technique for proving that a problem is NP -
complete, which may be useful when dealing with problems that are new.
This material is mathematically based, emphasizes fundamental (and long lasting) material
rather than the latest computer technology, and includes quite a few things that someone at the
very beginning of his career might not apply — yet. Each of these might explain why you don’t
often find a course like CPSC 413 offered by a community college or institute of technology.
However, the Department of Computer Science is part of the University of Calgary, and it’s
appropriate that we offer courses that cover the theoretical aspects of our discipline, as well as
material that’s useful to a senior developer or researcher, who’s trying to extend what’s known
already, or to improve industrial practices and standards, and not only to use what’s known already
or follow the practices and standards that are already in place.
Thus, it’s completely appropriate that CPSC 413 exists as a university course in computer
science. Similar courses are offered by computer science departments in numerous other universities,
so it’s a reasonably standard offering.
15
1.3.3 Why CPSC 413 is Required
As discussed in Section 1.3.1, the material covered in CPSC 413 really can be of value for researchers
in computer science and for developers as they rise through the ranks.
CPSC 413 is also one of a very small number of “theory” courses that students are required to
take in order to earn a BSc in Computer Science, and it is frequently the only course they take in
which they’re required to apply both calculus and discrete mathematics in order to solve problems
in computer science, and in which students are required to read and write nontrivial proofs that
include both written English and mathematical notation.
Thus, this course requires students to apply mathematics and exercise their communications
skills in ways that most other required courses don’t. Because of this, it’s also considered to be
valuable by researchers and developers who aren’t very interested in “algorithm design and analysis”
at all.
Finally, a course in the design and analysis of algorithms is now a fairly common requirement
for university-level computer science programs; requiring CPSC 413 helps to make our program
consistent with others.
16
Lecture notes for this block course are included in these notes; additional material may be
provided on the course web page (which is mentioned below).
17
1.6 How to Succeed in This Course
Many (but not all) students find CPSC 413 to be a difficult course. Here are some suggestions of
things you can do to increase the likelihood that you’ll do well in it.
Of course, it takes time to follow each of these suggestions, and there will be other things that
you’ll need to do during the term. It’s up to you to decide how much time you can afford to spend
on this course.
It’s also important to pay attention to this course early on, because so much of the material
in this course depends on earlier material (so that you generally need to understand the earlier
material and know how to solve the earlier problems, in order to be able to deal later with the later
ones), and since the early term work counts for quite a bit of your final grade.
18
Either way, you’ll be better off if you attempted the problems before attending the labs then
you would have been if you simply attended the labs without thinking about the problems first:
It’s easier to understand someone else’s solution of a problem than it is to solve it on your own.
Thus, the fact that you did understand the instructor’s solution of a problem doesn’t imply that
you’ll be able to solve a similar problem later on, and you don’t want to discover that you can’t
solve this kind of problem on your own in the middle of a test!
Finally, skipping the labs completely would be even worse than attending them without having
prepared for them first.
19
meant something else, after material has been marked and returned.
On the other hand, of course, if they really misread something, then you should point this out
(and expect a correction of your mark)!
20
Part II
21
Chapter 2
2.1 Overview
This chapter reviews proof techniques that were probably introduced in Math 271 and that may
also have been used in a different way in Phil 279. The first subsection introduces standard proof
techniques that will be used repeatedly in proofs presented in CPSC 413. The second subsection
presents what will probably be the most important proof technique for this course — mathematical
induction. It includes a “standard” form of mathematical induction, as well as several variations
that will be needed for algorithm analysis.
It’s expected that you’ve seen all the proof techniques included in Section 2.2, below, although
you might not have seen the names that have been given to these techniques here. It’s also expected
that you’ve seen at least the “standard” (simplest) form of mathematical induction presented in
Section 2.3.
On the other hand, some of the other versions of mathematical induction might be new to you!
They’re discussed here because they will be used, repeatedly, in CPSC 413, so it’s worthwhile to
study them now.
23
2.2.2 Direct Proofs
In a “direct proof” (or “forward proof”), you start by working with what can been assumed —
namely, the axioms you’ve been given — and you apply deduction rules to list other statements
that are logically implied by the ones you’ve listed already, until you’ve managed to include the
desired assertion P . One deduction rule that’s frequently useful here is modus ponens, which allows
you to deduce P from Q and Q → P , for any (other) assertion Q.
This “direct” method (of working forward from assertions to the desired conclusion) is often not
the way you discover a proof — sometimes you start with P and work backwards, and sometimes
you do a bit of both (working forward while it’s clear how to proceed, and also working backward
from desired conclusions in order to list a few other things that imply the conclusion and that
might be easier to prove first).
Even though this repeated forward and backward reasoning may be the way you develop a proof,
it’s often best if you write it up purely as a “forward” proof: That is, write it as if you started with
the axioms and applied deduction rules to establish additional things that were implied, including
and using axioms as needed, until P was included (and as if you never worked “backwards” at
all). When you do this you’ll be listing things in an order that’s different from the one in which
you originally considered things, and you’ll prune out “false starts,” et cetera, but the result will
generally be more readable (and seem better organized) than it would have been otherwise.
This does have the disadvantage, sometimes, of making it less clear how the proof was discovered,
that information isn’t strictly necessary, even though it might be interesting, and including it can
make the resulting proof harder to follow.
A→B
2. Proving B;
3. Noting that since you only assumed A in order to do this, you’ve proved A → B (“uncondi-
tionally” — that is, assuming only the original set of axioms without A).
This gives you one more “axiom” to work with and leaves you with a simpler assertion (B) to
prove, so this technique will be used virtually every time you need to prove a conditional.
A→B
¬B → ¬A
24
In other words,
Sometimes, it’s easier to try to prove the claim in the form ¬B → ¬A (that is, using ¬B as a
new assumption and ¬A as the desired conclusion) than it is to prove A → B more directly.
By the way, in case you’re used to seeing a different symbol for this: ¬ stands for “not,” so that
¬A is the negation of A.
Note, though, that A → B is not generally equivalent to B → A! It’s a common mistake to
“argue in the wrong direction,” by trying to prove “A → B” by assuming B and then deducing A
(instead of assuming A and deducing B).
(A ∧ ¬B) → (0 = 1)
or, perhaps
(A ∧ ¬B) → (C ∧ ¬C)
for some other proposition C, then you can safely conclude that
A→B
as desired.
∃xQ(x),
so that Q(x) is a statement about some unknown value “x,” and the claim is that there’s some
value v for x such that Q(v) is true, then you can prove this by establishing the conclusion
Q(u)
∀xQ(x)
Q(u)
is false, for any value u you choose (and, for which this can be proved).
25
2.2.7 Proof by Universal Generalization
The previous technique (establishing ∃xQ(x) by proving Q(u)) may seem obvious; the next one
probably won’t, but you’ll frequently need to use it too.
Suppose you wish to prove
∀xQ(x).
Q(u)
where the element u is arbitrarily chosen — meaning that the element “u” doesn’t appear in
any assumptions or axioms that you’re allowed to use in order to establish the desired result, and
that there are no (known) properties it has that other elements of the domain don’t have as well.
Sometimes (in Phil 279) such an element u is said to be “new.”
Proving something about a specific “generic” element u is conceptually easier than trying to
prove the same thing about all elements at once. Here’s an informal justification for the correctness
of this technique: If you managed to prove Q(u) when u is arbitrarily chosen, and if v is any other
element, then you should be able to replace every occurrence of u in your proof by an occurrence
of v, and end up with a proof of Q(v) instead. Since you can do this for any element v, ∀xQ(x)
must be true.
Note that u really must be “arbitrarily chosen,” or “new,” if this is to work: If, instead, u was
mentioned in axioms or prior assumptions, then replacing u by v in one of these might turn a true
(and known) statement into a false (or unknown) one, so that you might turn a correct proof into
an incorrect one. The fact that u is “arbitrarily chosen” keeps this from happening.
For example, suppose you’d established (or was given as an axiom) that 2 is a prime number.
Then you couldn’t prove that “every integer greater than or equal to one is prime” by choosing “u”
to be an “arbitrary” integer, “say, u = 2,” using the previous proof or axiom to deduce that u is
then prime, and then concluding that since “u is arbitrarily chosen and is prime, all integers that
are greater than or equal to one are prime.” The problem with this “proof” is that (since you’ve
set it to be equal to 2), u isn’t an “arbitrarily chosen integer that is greater than one” at all. While
it’s probably obvious that this “proof” is incorrect, you should make sure you don’t ever make the
same mistake in a more subtle way: Once you’ve declared u to be an “arbitrarily chosen” value,
you can’t really assume that u has any properties at all, unless you’ve proved already that every
value in the given range has them.
26
that any of them doesn’t use this assumption, then this is an “unconditional” proof of P — meaning
that it’s valid in all cases, so that you can throw away the proofs for the other cases and use this
single proof, without a case analysis, to establish P .
Axiom 2.1 (Division Theorem). If a and b are positive integers then there exists an integer
quotient q and an integer remainder r such that 0 ≤ r ≤ b − 1 and
a = bq + r.
Claim. For every positive integer x, either x is even or x + 1 is even (or both). That is, either
x = 2k for some integer k or x + 1 = 2k for some integer k, or both.
where E is the predicate “is even,” and the quantification ranges over all positive integers.
n = 2q + r. (2.1)
n + 1 = 2q + 2 = 2(q + 1).
Since q is an integer, q + 1 is an integer as well, so n + 1 is even. Again, this clearly implies that
either n is even or n + 1 is even.”
It follows by the above case analysis that “either n is even or n + 1 is even” is (always) true.
Finally, since n is arbitrarily chosen, it follows (by universal generalization) that either x is even
or x + 1 is even, for every positive integer x.
You should make sure you understand why this proof by “universal generalization”establishes
the desired result.
The “Division Theorem” was used here to identify an exhaustive set of two cases, essentially
that either n is congruent to 0 modulo 2 or n is congruent to 1 modulo 2. Once these cases
were identified, a “proof by case analysis” could be used to establish the desired property for the
“arbitrarily chosen” integer n.
27
2.3 Mathematical Induction
Recall that the natural numbers are the integers that are greater than or equal to zero — that is,
the elements of the set {0, 1, 2, . . . }.
It’ll often be true in CPSC 413 that we wish to prove that “P (n)” is true for every natural
number n, where P (x) is a some property of an unknown value x. “Mathematical induction” is a
technique for proving things of this form, and it will be used in CPSC 413 over and over again.
Justification
One way to convince yourself that this is a valid proof technique is to convince yourself that, if
you’ve successfully proved that P (0) is true and also completed the inductive step, then you can
prove that P (c) is true, for any fixed natural number c, using a longer proof (whose length depends
on c) that doesn’t use mathematical induction at all. At least, it doesn’t use mathematical induction
at the top “level:” you might have used induction again in either the basis or the inductive step of
your original proof.
For example, “P (0)” is proved in the basis, so this works for c = 0. To prove P (1), use the
basis to conclude that P (0) is true, and then use the inductive step to conclude that
P (0) → P (1).
Then deduce (using “modus ponens”) that P (1) is true as well. Thus, this also works for c = 1.
To prove “P (2),” first prove P (1) as above and then use the inductive step, again, to conclude
that
P (1) → P (2).
Use modus ponens to deduce that P (2) is also true. Thus this works for c = 2.
In general, you’ll need to start by using the basis and then use the inductive step c − 1 times
(for n = 0, 1, . . . , c − 1), in order to establish P (c) by this technique.
Example
Suppose now that we wish to prove the following.
Claim.
X
n
(2i − 1) = n2
i=1
28
X
n
That is, P (n) is the property (2i − 1) = n2 .
i=1
X
0
(2i − 1) = 02 .
i=1
The left hand side is an “empty sum” (a sum of zero terms), and this defined by convention to
be 0.
The right hand side is 02 , which is also equal to 0, so that the identity is correct.
Inductive Step: Now we wish to show that “P (n) → P (n + 1)” for every natural number n. That
is, we wish to show that
à n ! Ãn+1 !
X X
(2i − 1) = n2 → (2i − 1) = (n + 1)2
i=1 i=1
X
m
Since we only assumed that (2i − 1) = m2 , this implies unconditionally that
i=1
Ãm ! Ãm+1 !
X X
(2i − 1) = m 2
→ (2i − 1) = (m + 1)2
.
i=1 i=1
Now, since m was an “arbitrarily chosen” integer that is greater than or equal to zero, it follows
(by “universal generalization”) that
à n ! Ãn+1 !
X X
(2i − 1) = n2 → (2i − 1) = (n + 1)2
i=1 i=1
29
Conclusion:
It follows by induction on n that
X
n
(2i − 1) = n2
i=1
for all n ≥ 0.
Comments on This Proof: Note the use of “universal generalization” in the inductive step.
It will always be the case that universal generalization is needed at this point in the proof.
From now on this won’t be used quite so “explicitly” as it is here — in particular, this will be the
last time that the variable is renamed (to call it m instead of n) in order to highlight the fact that
universal generalization is being used.
The inductive step used another trick that is often useful when proving something about a
summation (especially in the inductive step for a proof by induction): we split the sum into two
pieces — one that we knew something about (the inductive hypothesis), and another that was easy
to compute.
The inductive step (specifically, the chain of equations near the middle of it) is part of the proof
that might have been discovered differently than it was written up. One might have started the
sum and got stuck, then worked “backwards” from the desired final result, (m+1)2 , hoping to meet
somewhere in the middle. After managing to use algebraic manipulation to equate both the left
hand side and the right hand side to some third expression (in this case, most likely, “m2 +2m+1”),
one could reverse the sequence of equations relating the middle value to the right hand side and
then concatenate the two sequences of equations together — obtaining the sequence of equations
shown above, as the form of the proof to be written up.
Definition
A proof that P (n) is true for every integer n ≥ k also has two parts:
Note that this is identical to the “standard” form of mathematical induction in the case that
k = 0.
Justification
One could argue that this works in essentially the same way that one can argue that the standard
form of mathematical induction works (as described in the “Justification” in the previous section).
Alternatively, you could argue more formally that this new proof method must be valid if the
standard form of mathematical induction is, by “defining” a new property Q(n) of integers as
Q(n) ≡ P (n + k).
30
Now, note that since P (k) ≡ Q(0), the “Basis” described above is identical to the “Basis” in
a proof that Q(n) is true for all n ≥ 0 that uses the standard form of mathematical induction.
Similarly, the “Inductive Step” described above is pretty much identical to the “Inductive Step” in
a proof that Q(n) is true for all n ≥ 0 that uses the standard form of mathematical induction as
well. That is, the two things to be established in the two “Inductive Steps” are obviously logically
equivalent, and it’s trivial to “transform” a proof needed for the one “inductive step” into a proof
that can be used to perform the other.
That is, if you prove both of the pieces given above (for P (n)), then you can conclude using
“standard” mathematical induction on n that Q(n) is true for all n ≥ 0.
Finally, you can note that, by definition, Q(n) is true for all n ≥ 0 if and only if P (n) is true
for all n ≥ k.
Example
Let’s make things easy (this is going to be long enough as it is) and suppose you’d like to prove
the following.
Claim.
X
n
(2i − 1) = n2
i=1
for every integer n such that n ≥ 2.
That is, the only difference between this and the first example is the different starting point,
k = 2.
Sketch of Proof. The basis include a proof of the identity
X
2
(2i − 1) = 22 ,
i=1
and it’s easy to verify that both the left hand side and the right hand side of this identity are equal
to 4 (after all, the left hand side is just 1 + 3).
The inductive step is also exactly the same as the inductive step for the first example, except
that you wish to prove that
à n ! Ãn+1 !
X X
(2i − 1) = n 2
→ (2i − 1) = (n + 1) 2
i=1 i=1
for every integer n such that n ≥ 2 (instead of, such that n ≥ 0). So, you suppose that n is an
arbitrarily chosen integer that is greater than or equal to 2 (instead of, greater than equal to 0),
proceed exactly as in the proof until you’re ready to draw conclusions. Then you observe that “since
n was an arbitrarily chosen integer greater than or equal to 2 (instead of 0), the result you’ve just
established must be true by universal generalization for every integer n ≥ 2 (instead of, for every
integer n ≥ 0). Finally, as before, you finish off by observing that you’ve now proved what you’d
hoped to, by induction on n.
If you’re confused about why the variable is called “n” throughout this argument, instead of
“n” some of the time and “m” the rest, see the “Comments on This Proof” that followed the proof
this is based on.
Finally, here’s a tedious but (I hope) straightforward exercise: Write out the proof that was
described above, just to make sure you know what it’s supposed to be.
31
2.3.3 Another Variation: Multiple Cases in Basis and Inductive Step
Sometimes it’s quite difficult to establish “P (n + 1)” if you can only assume “P (n),” but it’s easy
to establish P (n + 1) assuming P (n) and P (n − 1) — or more generally, that P (m) is true for the
previous “k” values of the integer m, for some positive constant k.
Definition
Suppose k is an integer that is greater than or equal to 1. In order to prove that P (n) is true for
every integer n greater than or equal to 0 by yet another form of mathematical induction, it is
sufficient to prove the following two things:
that is,
Ãk−1 !
^
P (n + i) → P (n + k).
i=0
Note that this is identical to the standard form of mathematical induction in the special case
that k = 1.
Justification
This time, you could convince yourself that the above rule is valid if and only if the standard form
of mathematical induction is, by starting with P (n) and defining Q(n) as
^
k−1
Q(n) ≡ P (n + i).
i=0
Once again, if you were to complete both of the proofs listed above (involving P (n)) then you
could use these to prove that Q(n) is true for every integer n ≥ 0, using the standard form of
mathematical induction applied to Q. Clearly (if k ≥ 1),
Q(n) → P (n)
for every integer n ≥ 0, so that P (n) is true for every integer n ≥ 0 if Q(n) is.
Example
Definition 2.2. If n ≥ 0 then the nth Fibonacci number, Fn , is defined as follows:
0 if n = 0,
Fn = 1 if n = 1,
F + Fn−2 if n ≥ 2.
n−1
32
Suppose we wish to prove the following bound.
Claim. If n ≥ 0 then Fn ≤ 2n−1 .
It will be difficult to prove this using the standard form of mathematical induction, because the
recursive definition of Fn (for n ≥ 2) involves both Fn−1 and Fn−2 . It will turn out to be easier to
prove this using the form of mathematical induction given above, choosing k = 2.
Note: Something like this will generally be the case, whenever you want to prove something about
recursively defined functions (recurrences) where the function fn being defined depends on more
than fn−1 . It will often be useful to choose “k” to be a positive integer such that fn is defined
(only) in terms of fn−1 , fn−2 , . . . , fn−k .
F1 = 1 ≤ 1 = 20 = 21−1
This implies unconditionally that if Fn ≤ 2n−1 and Fn+1 ≤ 2n+1−1 then Fn+2 ≤ 2n+2−1 .
Since n was an arbitrarily chosen nonnegative integer, this implies that if Fn ≤ 2n−1 and
Fn+1 ≤ 2n+1−1 then Fn+2 ≤ 2n+2−1 , for every natural number n, as is required to complete the
inductive step.
It therefore follows by induction on n that Fn ≤ 2n−1 for every natural number n.
33
Definition
A proof that P (n) is true for every integer n ≥ 0, using this final form of mathematical induction,
has two pieces:
2. Inductive Step: A proof that, for every integer n ≥ 0, if P (i) is true for every integer i such
that 0 ≤ i ≤ n, then P (n + 1) is true as well — that is, a proof that, for every integer n ≥ 0,
à !
^
n
P (i) → P (n + 1).
i=0
Justification
This time you could relate this to the standard form of mathematical induction by defining a
property Q(n) of n to be
^
n
Q(n) ≡ P (i).
i=0
If you complete both of the proofs (or “pieces”) described above for P (n) then you can use these to
produce the basis and inductive step in a proof, using the standard form of mathematical induction,
that Q(n) is true for every integer n ≥ 0. It should be clear that Q(n) → P (n) for every n, so this
implies that P (n) is true for every integer n ≥ 0, as well.
Example
Recall the definition of a binary tree as it was given in CPSC 331 (and, perhaps, in Math 271 before
that). Every node of the tree is either a leaf (if it does not have any children) or an internal node
(if it has at least one child). The depth of a binary tree is the length of the longest path (that is,
the number of edges) from the root of the tree to any leaf, while the size of a tree of the number
of nodes in it. By convention, an empty tree — one which has size 0 — is considered to have
depth −1.
Suppose now that we wish to prove the following.
Claim. For every integer d ≥ 0, every binary tree of depth d has size at least d + 1 and at most
2d+1 − 1.
Notation: In order to shorten the following proof, let P (d) be the assertion that “every binary tree
of depth d has size between d + 1 and 2d+1 − 1, inclusive,” for any nonnegative integer d. Then the
claim asserts that P (d) is true for every nonnegative integer d.
1≥1=0+1=d+1
34
and
1 ≤ 1 = 2 − 1 = 21 − 1 = 20+1 − 1 = 2d+1 − 1,
it is true that every tree of depth d has size at least d + 1 and at most 2d+1 − 1, when d = 0. (That
is, P (0) is true.)
Inductive Step: We now wish to prove, for every integer d ≥ 0, that if P (e) is true for every integer e
between 0 and d (inclusive) then P (d + 1) is true as well.
Suppose now that d is an (arbitrary) integer that is greater than or equal to 0. Next, suppose
that P (e) is true for every integer e between 0 and d.
Let T be an arbitrarily chosen binary tree of depth d + 1. Since d ≥ 0, d + 1 ≥ 0 as well, and
T is nonempty — that is, it has at least one node (its root).
It is therefore possible to split T into three pieces — with each of the last two possibly being
empty:
2. the left subtree of T (the subtree whose root is the left child of u, if this child exists); this
subtree is empty if u has no left child. We will call this subtree TL ;
3. the right subtree of T (the subtree whose root is the right child of u, if this child exists); this
subtree is empty if u has not right child. We will call this subtree TR .
Since d ≥ 0, d + 1 ≥ 1 and the root of T cannot be a leaf — otherwise T would have depth at
most 0 ≤ d. Therefore TL and TR can’t both be nonempty at once, and u is not a leaf of T .
Let dL and sL be the depth and size, respectively, of TL , and let dR and sR be the depth and
size, respectively, of TR . Then
sL , sR ≥ 0
dL , dR ≥ −1
s = sL + sR + 1
since every node in T is either the root, a node in TL , or a node in TR (but it can’t be more than
one of these at the same time).
It’s also true that the depth of T is exactly
max(1 + dL , 1 + dR ) = 1 + max(dL , dR ),
since any leaf of in T is either a leaf in TL or in TR , and its distance from the root of T is one plus
its distance from the root of the subtree (TL or TR ) to which it belongs.
On the other hand, T was chosen to be a binary tree of depth d + 1. Therefore (by comparison
of the two formulas for the depth of T that have been identified), max(dL , dR ) = d, so
35
Now, there are two cases to be considered — either dL = d or dR = d (or both). These cases
aren’t mutually exclusive — both could be applicable at once — but they are “exhaustive.” That
is, at least one case must always apply, so that it’s sufficient to prove that the desired inequalities
are correct in each of these cases in order to complete this part of the proof.
In the first case (dL = d), it follows by the inductive hypothesis that
d + 1 ≤ sL ≤ 2d+1 − 1.
Now, since sR ≥ 0,
s = sL + sR + 1 ≥ sL + 1 ≥ (d + 1) + 1
as desired, and all that is left for this case is to prove the desired upper bound on s as well.
Either TR is empty, or it is not. If TR is empty then dR = −1 and sR = 0, so the size s of T is
exactly sL + 1. Thus
s = sL + 1
≤ 2d+1 − 1 + 1 by the previous inequality
= (2d+1 + 1) − 1 reordering terms
≤2 d+2
−1 since 2 d+1
+ 1 ≤ 2d+2 if d ≥ 0
= 2(d+1)+1 − 1.
dR + 1 ≤ sR ≤ 2dR +1 − 1.
Thus
s = sL + sR + 1
≤ (2d+1 − 1) + (2dR +1 − 1) + 1
≤ (2d+1 − 1) + (2d+1 − 1) + 1 since dR ≤ d, and 2dR +1 ≤ 2d+1
= 2 · 2d+1 − 1
= 2(d+1)+1 − 1,
36
Since d is an arbitrarily chosen integer that is greater than or equal to 0, this implies that if
P (e) is true for every integer between 0 and d then P (d + 1) is true as well, for every nonnegative
integer d — completing the inductive step.
It therefore follows by induction on d that every binary tree of depth d has size between d + 1
and 2d+1 − 1, for every integer d ≥ 0, as desired.
Comments on This Proof: The two cases in the inductive step (dL = d and dR = d) are so similar,
that it might also have been acceptable to write, immediately after establishing that dL = d or
dR = d, “Suppose, without loss of generality, that dL = d (otherwise, one can exchange the subtrees
TL and TR );” and then just to give the proof for the first case, without mentioning the second case
again.
This is not the only way that one could prove this result, and it isn’t even the only way that
one could prove this using induction on d.
Finally, it should be noted that this last form of mathematical induction might be quite useful
whenever you’re trying to prove something about a data structure (at least, a graph or a tree) if it’s
recursively defined, or if there’s a way to split the structure into two or more pieces and examine
the pieces independently — and, as above, when you can’t relate the “size” (or “depth”) of the
pieces as closely to the “size” (or “depth”) of the original as precisely as you’d need to in order to
use one of the other forms of mathematical induction instead.
37
I hope that this made the proofs more readable than they’d have been otherwise. Since someone
else will be reading and marking) the proofs you develop for CPSC 413, these are things that you
should also be true of your proofs, when time permits.
2.5 Exercises
1. Prove that either n, n + 1, or n + 2 is exactly divisible by 3 for every integer n ≥ 0.
3. Recall the Fibonacci numbers, as given in Definition 2.2 (in Subsection 2.3.3).
Prove that Fn ≥ (3/2)n−2 for every integer n ≥ 2.
Use the definition of F0 and F1 given above to figure out what α and β must be, and then
prove that this formula is correct (for the values of α and β you’ve discovered) for all n ≥ 2,
as well.
5. Recall that a node of a binary tree is an internal node if it has at least one child, and that it
is a leaf otherwise.
The size of a binary tree is the number of nodes in the tree, which is the same as the sum of
the number of internal nodes and the number of leaves.
A binary tree is a complete binary tree if every internal nodes has exactly two children —
that is, if there are no internal nodes having only one child each.
Prove that every nonempty complete binary tree has exactly one more leaf than it has internal
nodes.
You’ll find hints for Exercises 2–5 in Section 2.6, below, and you’ll find a solution for Question 2
in Section 10.1. I recommend that you try to solve these exercises before you look at their hints or
solutions!
Exercise #3: This problem can be solved by developing a proof whose structure is similar to
the proof involving Fibonacci numbers in Section 2.3.3.
38
Exercise #4: You’ll need to start by figuring out what α and β are. You can do this by comparing
the values for F0 and F1 given in the definition of the Fibonacci numbers, to the values (involving
α and β) you get using the expression in the question. You should find that you end up with a
system of two linear equations in the two unknowns α and β, and that this system has a unique
solution.
Once you’ve done that, use yet another proof by induction whose structure is similar to the one
given above.
You might get stuck in the middle of the inductive step, but you may be able to “recover” by
working backwards from what you know that you need at the end, at this point.
Here’s a final hint: The two bases of powers in the expression in the question,
√ √
1+ 5 1− 5
and ,
2 2
turn out to be the roots of the polynomial x2 − x − 1, as you can verify by evaluating at the
polynomial using these values for x, or by using the binomial theorem. Of course this isn’t obvious
by inspection of these values, but this will turn out to be useful (and, this is the missing thing you
might “discover” that you need by working backwards at the end, as is suggested above).
Exercise #5: This problem can be solved using a proof by mathematical induction with the
same structure as the proof involving binary trees included in Section 2.3.4.
When you complete the inductive step, it may be useful to observe that any complete binary
tree of size greater than one has a left and right subtree of the root that are both nonempty.
39
40
Chapter 3
3.1 Overview
This is the first of two chapters reviewing material from calculus; limits and derivatives are discussed
in this chapter, and integrals will be discussed in the next.
While formal definitions of limits and derivatives are included, for the sake of completeness, these
won’t be used very much in CPSC 413; you should concentrate more on the rules for computing
limits and derivatives that this chapter includes.
3.2 Limits
3.2.1 Informal Introduction
You should remember from Math 249 or 251 that “limits reveal the behaviour of a function near a
point.”
Consider, for example, the function f (x) = x2 + 1. A graph of the function near x = 1, and
the function values f (0.9) = 1.81, f (0.99) = 1.9801, f (0.999) = 1.998001, as well as f (1.1) = 2.21,
f (1.01) = 2.0201, and f (1.001) = 2.002001, should both suggest that the limit of the value of this
function as x approaches 1 is 2. That is, these should suggest that
lim f (x) = 2.
x→1
Of course, this is f (1) in this case, so that for this example the limit of the value of the function as
x approaches 1 is just f (1).
This isn’t always true. For example,
• If f (x) = x1 then there is no limit of the value f (x) as x approaches 0: The value diverges to
+∞ as x approaches 0 “from the right” (that is, as x takes on progressively smaller positive
values), and it diverges to −∞ as x approaches 0 “from the left” (that is, as x takes on
progressively smaller negative values).
√
• If f (x) = xx then the limit of f (x) does not exist as x approaches 0. This time, though, the
value approaches 1 from the right and −1 from the left (and, again f (0) is not defined).
41
√
2
• If f (x) = |x|x
, then the limit of f (x) exists as x approaches 0, and the limit equals 1, but
f (0) is not defined. In fact, f (x) = 1 for all x except when x = 0.
• Finally, if
(
1 if x 6= 0
f (x) =
0 if x = 0,
then the limit of f (x) as x approaches 0 exists, and f (0) exists, but these values aren’t the
same: The limit is 1 and the function value is 0.
lim f (x) = L,
x→a
if, for every real number ² > 0, there exists some real number δ > 0 such that
Note (again) that this does not imply that f (a) = L, or even that f (a) is defined, because the
definition only mentions a condition that must hold when |x − a| is strictly greater than zero.
In CPSC 413 we’ll frequently be interested in the limits of function values as x becomes arbi-
trarily large (as x approaches +∞):
Definition 3.1, Continued:
The limit of f (x) as x approaches +∞ exists and is equal to (a finite constant) L,
lim f (x) = L,
x→+∞
if, for every real number ² > 0, there exists some (generally, large) real number M > 0 such that
lim f (x) = +∞
x→+∞
if, for every real number U > 0, there exists some (generally, large) real number M > 0 such that
42
If all else fails, then it is occasionally possible to “prove” that lim f (x) = L using this definition.
x→a
Suppose again, for example, that f (x) = x2 + 1 and let a = 1. To prove formally (from the
definition) that lim f (x) = L in this case, for L = 2, suppose that ∆ is a small real number, and
x→a
note that
f (1 + ∆) = (1 + ∆)2 + 1 = 2 + 2∆ + ∆2 .
It is sufficient to consider small values for ∆, so suppose now that |∆| < 1. Then |∆2 | < |∆| and
it follows from the above that
|f (1 + ∆) − 2| < 3|∆|.
Now, given any positive real number ², we can choose δ to the the minimum of 1 and ²/3. Then
δ is also a positive real number, and it follows from the above derivation that
|f (x) − 2| < ²
whenever
|x − 1| < δ,
43
where, as usual, bxc is the largest integer that’s less than or equal to x (and is called the floor of x).
Note that f (n) = fˆ(n) for every integer n according to this definition.
Now we’ll just define lim f (n) to be the same as lim fˆ(x), so that the evaluation rules can
n→+∞ x→+∞
be applied to the second of these limits, in order to find the value for the first one.
You might be concerned because there are several different ways to extend a function that’s
defined on the integers, to get a function that’s defined on the reals. If any of the extensions has a
limit, then this really will be the limit (as n approaches infinity) of the integer function you started
with — and all of the other possible extensions will either have the same limit or won’t have any
limit at all. Furthermore, the extension suggested above (involving the use of bxc as an argument)
will have a limit if any of the extensions do.
Another way to deal with this problem will be given as part of Theorem 3.6, below.
Finally, please note that the above tricks are only recommended when you want to compute
a limit at infinity — don’t apply them if you want to compute limits as the evaluation point
approaches a finite value!
Theorem 3.2 (Limit of a Constant). If f (x) = c (that is, f is a constant function), then
lim f (x) = c
x→a
for functions f and g, finite values L and M , and for any real or complex number a (or for
a = +∞). Then
and
Theorem 3.4 (Quotient Rule). If a, f (x), g(x), L and M are as above, and M 6= 0, then
f (x) L
lim = .
x→a g(x) M
44
You can extend these rules to some of the cases where one or both of L and M equal plus or
minus infinity. Unfortunately, there are some cases where you can’t: The sum
(+∞) + (−∞)
then
f (x) · h(x) f (x)
lim = lim .
x→a g(x) · h(x) x→a g(x)
then
f (x) · h(x) f (x)
lim = lim .
x→+∞ g(x) · h(x) x→+∞ g(x)
That is, you can “cancel out” the common factor of h(x) in the numerator and denominator
without changing the limit in each case. Sometimes this is all you need to do in order to go ahead
and compute the limit.
For example, consider the limit
3x
lim .
x→0 2x
Let h(x) = x; then h(x) is nonzero when x is close to 0, in the sense given above, even though
h(0) = 0, and the limit has the form described above for f (x) = 3 and g(x) = 2. So we can use
Theorem 3.5 to conclude that
3x 3 3
lim = lim = .
x→0 2x x→0 2 2
Here’s another fact that is occasionally useful. This doesn’t only apply to limits of ratios, but
it can definitely be useful in this case.
Theorem 3.6 (Sandwiching the Limit). Let f , g, and h be functions that are defined on the
real numbers such that, for a finite constant a and positive real number δ,
45
Suppose, furthermore, that
then
as well.
Similarly, if f , g, and h are functions that are defined on the real numbers and N is a (generally
large) constant such that
and
then
as well.
Finally, if f and h are functions that are defined on the reals, g is a function that is defined on
the integers, and N is a (generally large) constant such that (for integers n and real numbers x)
and
then
as well.
This result can be applied — to compute the middle limit for g — as long as f and h really do
provide lower and upper bounds on g within the range you’re interested in (that is, near the limit
point), and as long as the limits of f and h really do agree.
Here’s an example: Suppose you want to compute the limit
2n
lim
n→+∞ n!
It isn’t clear how you can do this directly. On the other hand, since
Y
n
n! = i,
i=1
46
it isn’t too hard to see that if n ≥ 1 then
2 n Yn Yn Yn
· 3 = 2 · 3n−2 = 1 · 2 · 3≤1·2· i = n! ≤ n = nn ,
9 i=3 i=3 i=1
so that
µ ¶n
2n 2n 9 2n 9 2
≤ ≤ · = · . (3.2)
nn n! 2 3n 2 3
Set
µ ¶x
9 2
h(x) = · ;
2 3
then clearly h is defined on the real numbers, and
µ ¶x
2 2 2
lim h(x) = lim · = 0, since 0 ≤ < 1.
x→+∞ x→+∞ 3 3 3
x
We could try to set f (x) to be x2x (based on the inequality given above) and apply the method
being described.
x
However, it’ll make things easier if we simply observe that x2x is nonnegative for all x ≥ 0, and
use the inequality
µ ¶n
2n 9 2
0≤ ≤ ·
n! 2 3
for every natural number n that is implied by this observation and by inequality (3.2), above.
n
Therefore we’ll set f (x) = 0, g(n) = 2n! , and h(x) to be as defined above, and we’ll set N to
be 1. Then
lim g(n) = 0
n→0
as well. Note that this is the limit that we originally wished to compute.
We’ll see one more extremely useful rule to compute the limits of ratios, after defining derivatives.
A function is continuous on an interval if it’s continuous at every point inside that interval, and
it’s continuous if it’s continuous at every real number.
47
By definition, the limits of continuous functions are extremely easy to compute: the limit of a
continuous function is just the value of the function at the limit point.
Polynomials and exponential functions are continuous, and log functions (f (x) = logc x for some
constant c > 0) are continuous on the interval of positive real numbers. You may use these facts
without having to prove them in CPSC 413.
Of course, this still leaves us with the problem of computing limits as x approaches +∞.
3.3 Derivatives
3.3.1 Definitions
Suppose f (x) is a function and a is a real number such that f is continuous at a. Informally (or
graphically), you can think of f 0 (a) as the slope of the line that is tangent to the graph y = f (x)
at the point (a, f (a)). If f is not continuous at a then f 0 (a) doesn’t exist.
The derivative of f at a can be defined more formally as a limit:
If f is differentiable then we’ll frequently consider f 0 to be a function as well — that is, we’ll
refer to the function f 0 (x) (or just f 0 ), with the understanding that the value of this function at
any real number a is the limit f 0 (a) given above.
Theorem 3.10 (Derivative of a Power). If f (x) = xα , for any fixed real number α, then f is
differentiable and f 0 (x) = α · xα−1 . In particular, the derivative of 1 (the function x0 ) is 0.
Theorem 3.11 (Sum, Product, and Quotient Rules). If functions f and g are both differen-
tiable at a, then
and
48
Theorem 3.9 and the above sum and product rules can be used to establish that differentiation
is a linear operator: If c is a constant and f , g, and h are functions such that f (x) = c · g(x) + h(x),
then f 0 (x) = c · g 0 (x) + h0 (x) as well.
or
then
f (x) f 0 (x)
lim = lim 0
x→a g(x) x→a g (x)
(provided, of course, that the derivatives shown in the above expression exist). That is, you can
differentiate the functions in the numerator and in the denominator, without changing the limit, in
these cases.
The first example of the use of l’Hôpital’s rule you saw might have been the following: Suppose
f (x) = sin x and g(x) = x; then lim f (x) = lim g(x) = 0. So, by l’Hôpital’s rule,
x→0 x→0
sin x cos x
lim = lim = cos 0 = 1,
x→0 x x→0 1
since f 0 (x) = cos x if f (x) = sin x and g 0 (x) = 1 if g(x) = x, and since the cosine function is
continuous.
Note, again, that you can only apply this rule if either f (x) and g(x) both approach 0 or if they
both approach +∞ at the limit you want to compute. On the other hand, you won’t need this rule
in any other case.
49
Definition 3.14. Euler’s constant, commonly written as e, is the limit
µ ¶n
1
lim 1+
n→+∞ n
and is approximately equal to 2.71828 . . .
Theorem 3.15. If f (x) = ex then f 0 (x) = ex as well.
Definition 3.16. If x > 0 then the natural logarithm of x, ln x, is the (unique!) real number y
such that ey = x. Thus if g(x) = ln x and f (x) = ex as above, then
3.6 Exercises
1. Compute the each of the following limits or explain why it does not exist.
x3 − 8
(a) lim
x→2 x − 2
x2 + 2x + 1
(b) lim
x→+∞ 3x2 + 5
x
(c) lim
x→0 cos x − 1
sin(4x)
(d) lim
x→0 sin(3x)
50
2. Compute the derivative (with respect to x) of each of the following functions.
3. Derive the quotient rule (as given below), starting with the definition of a derivative, and
assuming that the functions f and g are both differentiable at a and that g(a) 6= 0.
f (x)
Quotient Rule: If h(x) = g(x) then
4. Prove that
(ln x)n
lim =0
x→+∞ x
for every natural number n ≥ 1.
Hints for selected exercises are given in the next section; solutions for Exercises 1(c) and 3 are
given in Section 10.2.
Exercise #1(b): You can either treat x2 as a common factor to be eliminated from both the
numerator and denominator, or you can apply l’Hôpital’s rule twice.
Exercise #1(d): Apply l’Hôpital’s rule. You’ll need to treat both the numerator and denomi-
nator as compositions of functions and use the chain rule to compute the needed derivatives.
Exercise #2(d): f (x) = g(h(x)) for g(y) = ey and h(z) = z 2 ln z. Apply the product rule to
differentiate h, and then apply the chain rule to differentiate f .
Exercise #4: Try to prove this using mathematical induction, by induction on n (with n = 1 as
your starting point). You’ll probably need to apply l’Hôpital’s rule in both the basis and inductive
step of your proof.
51
52
Chapter 4
4.1 Overview
This chapter continues the review of Math 249 or 251, and presents definitions and rules for com-
puting antiderivatives and integrals (also known as indefinite and definite integrals, respectively).
Once again, the formal definitions given here are generally less important for CPSC 413 than the
evaluation rules that follow them.
At least one of the evaluation rules — “Integration by Parts” — might not have been covered in
Math 249 or 251. Therefore, while this is an easy rule to learn, it won’t be required for CPSC 413
assignments or tests; at most, it will be used in the occasional example that’s presented in lectures
or labs.
4.2 Antiderivatives
Definition 4.1. An antiderivative of a function f (x) is another function g(x) whose derivative
g 0 (x) is equal to f (x).
An antiderivative of f (x) is sometimes called an “indefinite integral” of f (x). Any such function
is denoted
Z
f (x) dx
53
Theorem 4.3 (Antiderivative of the Exponential Function).
Z
ex dx = ex + C.
and may be interpreted as the area of the region bounded by the graph y = f (x), the x-axis, and
the vertical lines x = a and x = b (for a < b). Any area within this region that is above the x-axis
is given a positive value, and any area below the x-axis is given a negative value.
This area is easy to compute if f (x) is a linear function (and you remember how to compute
the area of a triangle); it isn’t so clear how to compute this, for more general functions.
Thus, we can compute definite integrals if we know how to find (and evaluate) antiderivatives.
54
Theorem 4.7. Let a and b be real numbers such that a ≤ b and let f (x) be a function that is
continuous on the closed interval between a and b. Then
Z µ ¶ n
b b−a X
f (x) dx = lim f (xi ).
a n→+∞ n i=1
Numerical integration packages use sums like this one — although they generally use ones that
converge to the limit faster than this one — in order to estimate the values of definite integrals;
these packages are studied in CPSC 491. We’ll see a different use for this in CPSC 413 when we
consider “summations.”
Integration by Substitution
Recall the chain rule: If H(x) = F ◦ G(x) = F (G(x)), then H 0 (x) = F 0 (y) · G0 (x), for y = G(x).
We can “reverse” this differentiation formula to obtain an integration formula.
for functions f (x), g(x), and G(x) such that G0 (x) = g(x), and if F (x) is a function such that
F 0 (x) = f (x), then
Z
h(x) dx = F (G(x)) + C.
In order to apply this we’ll generally perform the following steps, given the function h(x).
1. Guess (or somehow find) a function G(x) and set g(x) = G0 (x).
2. Define the function f using the rule f (y) = h(x)/g(x), for y = G(x).
For example, suppose that h(x) = (sin x) · (cos x), and suppose we “guess” that G(x) = sin x.
Then g(x) = G0 (x) = cos x, y = G(x) = sin x, and we have f (y) = h(x)/g(x) = sin x = y.
Thus, f (x) = x.
Now, an antiderivative of f (x) is easy to find: we can choose F (x) = 12 x2 +C for any constant C.
We now return H(x) = F (G(x)) = 12 (sin x)2 + C as an antiderivative of h(x). Differentiation
confirms that H 0 (x) = h(x), as desired.
For another example, suppose h(x) = sin(x + 1), and guess that G(x) = x + 1, so that g(x) =
G0 (x)= 1. Then y = G(x) = x + 1, f (y) = h(x)/g(x) = sin(x + 1) = sin y (so that f (x) = sin x),
and we can guess (or look up) an antiderivative of f (x): F (x) = −(cos x) + C.
We now return the antiderivative H(x) = F (G(x)) = −(cos(x + 1)) + C; differentiation confirms
that H 0 (x) = h(x), as desired.
55
Integration by Parts
Now recall the product rule: If h(x) = f (x)·g(x), then h0 (x) = f 0 (x)·g(x)+f (x)·g 0 (x). Subtracting
the last term from both sides (and reversing the left and right hand sides) gives the equation
f (x) · g 0 (x) = h0 (x) − f 0 (x) · g(x),
and integrating both sides (and using linearity) gives the following rule.
Theorem 4.9 (Integration by Parts).
Z Z
0
(f (x) · g (x)) dx = f (x) · g(x) − (f 0 (x) · g(x)) dx.
This is sometimes useful, because we’re given a function of the form f (x)·g 0 (x) to be integrated,
and it’s easier to find an antiderivative of f 0 (x) · g(x), instead.
Suppose, for example, that we wish to integrate the function h(x) = x · ex . Then we can write
this as h(x) = f (x) · g 0 (x), where f (x) = x and g 0 (x) = ex . Clearly f 0 (x) = 1 and one antiderivative
of g 0 (x) is g(x) = ex , so we have that
Z Z
xe dx = xe −
x x
1 · ex dx = xex − ex .
Differentiating the function on the right confirms that this answer is correct.
4.4 Exercises
Compute each of the following integrals, assuming a and b are positive real numbers such that
b > a > 1.
Rbx3 −1
1. a x−1dx
R √
2. ab (2 − x) dx
Rb
3. a ex dx
Rb 1
4. a x+ x dx
Rb 1
5. a x−1 dx
Rb (ln x)3
6. a x dx
Rb
7. a x2 ex dx
Rb 1
8. a (x−1)(x+1) dx (This one is challenging!)
Hints for these problems are given in Section 4.5, below, and a solution for Question 6 appears
in Section 10.3.
56
4.5.1 First Set of Hints
Exercise #1: The integral can be calculated by performing a simple algebraic substitution: Note
that a > 1 and that x − 1 is a factor of the numerator of the expression to be integrated.
Exercise #5: You might calculate this integral by using an application of “integration by sub-
stitution” resembling one of the examples given in Section 4.3.3.
Exercise #6: Consider “integration by substitution” for this integral as well. One of the func-
tions involved will be the natural logarithm, ln x.
Exercise #8: You’ll probably need to manipulate the expression to be integrated in order to
compute this integral. Rational functions can be decomposed in a particular way; in particular,
there exist constants c1 and c2 such that
1 c1 c2
= + .
(x − 1)(x + 1) x+1 x−1
Since the two expressions are equal, their integrals are equal as well. However, you’ll probably find
it easier to integrate the version on the right hand side than the one on the left.
Exercise #5: To use integration by substitution, “guess” that G(x) = x − 1, so that g(x) = 1.
You should then find that f (y) = y1 .
R R
Exercise #7: x2 ex dx = f (x) R· g 0 (x) dx, where f (x) = x2 and g 0 (x) = ex . Recall that (after
reading Chapter 4) you know what xex dx is already!
Exercise #8: See the original hint for this problem, and try c1 = 1
2 and c2 = − 12 (or, perhaps,
vice-versa).
57
58
Chapter 5
Sample Tests
While there wasn’t a “math review” for CPSC 413 at all in 1996, most of the questions on the first
class test for that year were essentially on “math review” material, so this test is reproduced below
in Section 5.1.
On the other hand, there was a math review in 1997. The first class test for CPSC 413 that
year was actually a “mock test” — it didn’t count — and it was completely based on the material
presented in the math review that year. It’s reproduced, below, in Section 5.2.
1. Consider two algorithms, “Algorithm A” and “Algorithm B,” for the same problem. Algo-
rithm A uses 4n2 steps to solve a problem of size n while Algorithm B uses 100n steps to
solve a problem of the same size.
(a) (2 marks) For which inputs sizes (values of n) would Algorithm A be at least as fast as
Algorithm B?
(b) (3 marks) Suppose Algorithm A can be used to solve a problem of size s in time t on one
computer. What is the size of a problem that could be solved using the same algorithm,
on a new computer that is 100 times as fast?
3. (10 marks) Recall that every node in a binary tree is either an internal node (if it has either
one or two children) or a leaf (if it does not have any children).
Prove that if a binary tree has exactly l leaves and i internal nodes, then l ≤ i + 1.
59
5.2 Class Test for 1997
Instructions:
Attempt all questions. Write answers in the spaces provided below.
No aids allowed.
Total marks available: 25
Duration: 50 minutes.
Note: This quiz will not be marked or count toward your CPSC 413 grade.
x ln x
1. (4 marks) Compute lim .
x→+∞ x1.5
2. Compute the derivative f 0 (x) for each of the following functions f .
60
Part III
Analysis of Algorithms
61
Chapter 6
Asymptotic Notation
6.1 Overview
This chapter includes a formal definition of the “big-Oh” notation that has been used in previous
courses to state asymptotic upper bounds for the resources used by algorithms, and introduces
additional notation for additional kinds of asymptotic bounds. It also introduces techniques that
can be used to compare the rates of growths of the kinds of functions that might arise as resource
bounds.
It is expected that CPSC 413 students will know the definitions that are presented here, and
that they will be able to apply the techniques for comparing functions that this chapter introduces.
Students should also be able to use the definitions to prove various properties of asymptotic nota-
tion. A set of exercises and sample tests is given at the end of this chapter (and can be used to
assess each of the above skills).
The most generally useful of these techniques require the computation of limits, and differen-
tiation of functions, so it might be helpful to review the material in Chapter 3 before attempting
the exercises in this chapter.
63
Definition 6.1. The worst case running time of an algorithm is a partial function from the set
of nonnegative integers to the set of nonnegative real numbers. In particular, the value of this
function at any integer n ≥ 0 is the maximum1 of the running times used by the given algorithm
on (all of the) possible inputs for the algorithm with size n.
The value of this function for small inputs is often extremely important. However, in this
course, we’ll be concentrating on the behaviour of these functions for large inputs instead. As
argued in Chapter 1, this can be extremely important for at least some problems and applications.
Note that the last part of this says that f (n) is strictly greater than 0, and not just “greater
than or equal to zero.”
6.3.1 Examples
For example, the function f (n) = n−1 is asymptotically positive, since f (n) is defined and f (n) > 0
whenever n ≥ 2. That is, you can set N to be 2 (or, any integer that’s greater than or equal to 2)
and observe that the function f satisfies the definition with this choice.
On the other hand, the function f (n) = sin n is not asymptotically positive, since there are
infinitely many positive integers n such that sin n is zero or negative (regardless of whether n
represents a number of degrees or radians).
Here’s another positive example, which includes a more substantial proof.
where cd , cd−1 , cd−2 , . . . , c0 are real numbers and cd is nonzero (so that f has degree d and leading
coefficient cd ). Then f is an asymptotically positive function if and only if cd > 0.
Proof of Claim. Since cd is nonzero, and is a real number, either cd > 0 or cd < 0. In order to
prove the claim, it’s necessary and sufficient to show that f (n) is always asymptotically positive
when cd > 0 and that f (n) is never asymptotically positive when cd < 0.
Suppose first that cd > 0. Then, since ci ≥ −|ci | for 0 ≤ i ≤ d − 1, if n ≥ 1 then
64
Now, if
This clearly implies that there are infinitely many nonnegative integers n such that f (n) < 0 —
and f (n) can’t possibly be “asymptotically positive” in this case.
This example has been given in hopes that it will help students to understand the definition of an
asymptotically positive function — not because students will be expected to develop similar proofs
themselves. On the other hand, students should remember the claimed result about polynomials
and should be prepared to use it without proof, as needed.
Fact 6.3. The functions f (n) = logc n and g(n) = cn are asymptotically positive, for any positive
constant c.
Fact 6.4. If f and g are asymptotically positive functions then f + g, f · g, and f /g are all
asymptotically positive functions as well.
Fact 6.5. If f is asymptotically positive and there exists an integer N such that g(n) is defined
for every integer n ≥ N (as is true, for example, if g is also asymptotically positive), then f g is
asymptotically positive as well.
On the other hand, it isn’t always true that the difference f − g of two asymptotically positive
functions f and g are asymptotically positive!
Students who wish to test their understanding of the definition, and who want to exercise their
skills in developing proofs, should try to prove each of the above facts.
65
6.3.3 Extensions of the Definition
It should be noted that you can define “asymptotically positive functions” whose domains are
subsets of the set of real numbers as well. In this case the definition would require that there is an
integer N ≥ 0 such that
All of the definitions that are given below are stated for asymptotically positive functions that
are defined on the integers. However, you can modify them, to obtain the corresponding definitions
for functions defined on the reals, by making one (and only one) change — and making it all the
time: just replace the specification that n is an integer by a specification that n is a real number
— just as happened above, in the definition for “asymptotically positive.”
Definition 6.6. If f and g are asymptotically positive functions then f ∈ O(g) if there exist
constants c > 0 and N ≥ 0 such that
for every integer n ≥ N , f (n) and g(n) are both defined, and f (n) ≤ c · g(n).
Informally, this means that f can’t grow asymptotically more quickly than g does. Note that it
does not imply that f and g grow asymptotically at the same rate: As defined here, it is possible
that f ∈ O(g) even though f grows “strictly more slowly” than g (and, this may be different from
the way you’ve seen the notation used before).
This effectively defines “O(g)” to be a set of asymptotically positive functions (and says when
a given function f belongs to this set).
Examples
As the following examples indicate, the above definition can sometimes be used to prove that
f ∈ O(g) for asymptotically positive functions f and g. It can also be used to establish that
f 6∈ O(g) in some cases.
Example 6.7. If f (n) = 2n and g(n) = n then it suffices to set c = 2 and N = 0, and then observe
that f (n) and g(n) are both defined and f (n) ≤ cg(n) whenever n ≥ N (indeed, f (n) = cg(n) for
this choice of c), to prove that f ∈ O(g).
66
You could also set c to be any constant that is greater than 2, and you could set N to be any
constant that is greater than 0, in order to prove this: There’s no need to choose constants that
are minimal — and choosing ones that are a bit larger than necessary sometimes makes it easier
to prove what you need to.
All of the remaining examples involve total functions, just as this first one did. We won’t always
bother to mention the fact that f (n) (or g(n)) is always defined for sufficiently large n in these
cases — but you should understand that this is a necessary part of the above definition, and that
it isn’t always trivial to prove this.
As the next example indicates, there are sometimes “tradeoffs” between the choices of these
two constants as well.
Example 6.8. If f (n) = 2n + 10 and g(n) = n then you could establish that f ∈ O(g) by setting
c to be 12 and N to be 1 — for 2n + 10 ≤ 2n + 10n = 12n whenever n ≥ 1. On the other hand,
you could set c to be 3 and N to be 10 — for 2n + 10 ≤ 2n + n = 3n whenever n ≥ 10. You could
also set c to be 12 and N to be 10 — but you couldn’t set c to be 3 and N to be 1 (write down the
corresponding condition on n and observe that it’s false in this last case). In this case, the larger
you set c to be, the smaller (and closer to 1) you can set N to be.
It’s also true, for each of the above examples, that g ∈ O(f ).
Example 6.9. To see that this isn’t always the case, let f (n) = n and g(n) = n2 . Note that you
can establish that f ∈ O(g) by choosing c = 1 and N = 1.
However, g 6∈ O(f ),
To prove this, suppose instead that g ∈ O(f ). Then there exist constants c > 0 and N such
that f (n) and g(n) are both defined and g(n) ≤ cf (n), for every integer n ≥ N .
In particular, this condition must be satisfied for some integer n that is greater than or equal
to both N and c + 1. However, in this case (since c and n are both positive, and c < n)
cn < n2 = g(n) ≤ cf (n) = cn,
which is clearly impossible — for cn can’t be strictly less than itself!
Since the only thing we assumed in order to establish this contradiction was that g ∈ O(f ), it
follows that g 6∈ O(f ), as claimed above.
Thus, the fact that f ∈ O(g) for some pair of asymptotically positive functions f and g does
not imply that g ∈ O(f ) in every case.
Example 6.10. Next let f (n) = 3 + sin n and g(n) = 1. Then (since 2 ≤ f (n) ≤ 4 for every
integer n), you can choose constants c = 4 and N = 0 and then confirm that the condition given
in the definition is satisfied with this choice of constants, in order to conclude that f ∈ O(g).
You should be able to prove that g ∈ O(f ) in this case, too.
Example 6.11. Finally, suppose that f (n) = n2 and
(
n if n is odd,
g(n) =
n3 if n is even.
Then you can prove that f 6∈ O(g) by assuming that f ∈ O(g) and obtaining a contradiction, as
in the third example above (and by considering the values of these functions at large odd inputs).
You should also be able to prove that g 6∈ O(f ), by assuming that g ∈ O(f ) and obtaining a
contradiction (by considering even inputs instead of odd).
Thus there are asymptotically positive functions that are “incomparable” as far as this “big-Oh”
notation is concerned.
67
These examples will be considered again in the remaining sections of this chapter.
Theorem 6.12 (Limit Test for O(f )). If f and g are asymptotically positive functions and
f (n)
lim
n→+∞ g(n)
exists and is finite (that is, not equal to +∞), then f ∈ O(g).
Proof. Suppose, as in the statement of the theorem, that the given limit exists and is a constant,
so that there is some constant L such that
f (n)
lim = L.
n→+∞ g(n)
Since f and g are both asymptotically positive, so that f (n) and g(n) are both defined and
f (n)/g(n) ≥ 0 for all sufficiently large integers n, it must be the case that L ≥ 0.
It follows by Definition 3.1 (and using 1 as the value for the constant ² mentioned in the
definition) that there is some real number M1 such that
¯ ¯
¯ f (n) ¯
¯
if n > M1 then ¯ − L¯¯ < 1. (6.1)
g(n)
It’s also true that f and g are asymptotically positive, so that there exists a constant M2 such
that f (n) and g(n) are both defined and positive for every integer n ≥ M2 .
Now let c = L + 1 and let N = 1 + max(M1 , M2 ). Equation 6.1, above, applies that if n is any
integer that is greater than or equal to N then (since n > M1 )
f (n)
− L < 1,
g(n)
so that
f (n)
< L + 1 = c.
g(n)
On the other hand, since n ≥ M2 , g(n) > 0, so that the above inequality implies that
CPSC 413 students won’t be expected to be able to reproduce the above proof, but they should
understand it. They should also be able to use the above theorem in order to prove that f ∈ O(g)
by computing
f (n)
lim
n→+∞ g(n)
68
and observing that it is a constant (when this is the case!).
In order to do this, it’s necessary to compute the limit as n approaches infinity of a ratio
f (n)/g(n) of functions f and g, where f and g both approach infinity. The techniques for computing
limits given in Chapter 3 will be useful as you try to do this.
Note that the above theorem does not say that it’s necessary for the above limit to exist
whenever f ∈ O(g), and we’ll see, shortly, that it’s possible that f ∈ O(g) even though the above
limit test “fails.”
On the other hand, you can conclude that f 6∈ O(g) if the limit test “fails” in one particular
way:
Theorem 6.13 (Negative Limit Test for O(f )). If f and g are asymptotically positive func-
tions and
f (n)
lim = +∞
n→+∞ g(n)
then f 6∈ O(g).
Proof. Suppose, instead that
f (n)
lim = +∞
n→+∞ g(n)
and f ∈ O(g) for some pair of asymptotically positive functions f and g.
Since f and g are asymptotically positive, there exists a constant M1 such that f (n) and g(n)
are both defined and positive for every integer n ≥ M1 .
Since f ∈ O(g) there exists constants c > 0 and N such that f (n) and g(n) are both defined
and f (n) ≤ cg(n), for every integer n ≥ N .
On the other hand, since
f (n)
lim = +∞,
n→+∞ g(n)
there exists a constant M2 such that
f (n)
>c
g(n)
for every integer n ≥ M2 (see the continuation of Definition 3.1, taking “U ” to be c).
The above three conditions imply that if n is any integer that is greater than max(M1 , N, M2 )
then
f (n)
c< ≤c
g(n)
(since g(n) > 0 in this case, so that it’s possible to divide by g(n) without changing the direction
of an inequality).
This is clearly impossible, since c can’t be strictly less than itself.
It follows that if
f (n)
lim = +∞
n→+∞ g(n)
69
Examples
Consider the examples given above.
If f (n) = 2n and g(n) = n as in Example 6.7 on page 66, then cancellation of a common factor
can be used to compute the limit you need (see Theorem 3.5 on page 45):
f (n) 2n 2
lim = lim = lim = 2.
n→+∞ g(n) n→+∞ n n→+∞ 1
Here, the common factor being cancelled from the numerator and denominator is clearly n.
Since the limit has been shown to be a constant, we can conclude that f ∈ O(g).
Cancellation can also be used to compute the desired limit in the case that f (n) = 2n + 10 and
g(n) = n (as in Example 6.8):
f (n) 2n + 10
lim = lim
n→+∞ g(n) n→+∞n
(2 + 10/n)n
= lim
n→+∞ 1·n
2 + 10/n
= lim
n→+∞ 1
= lim 2 + 10/n
n→+∞
= 2.
70
Using l’Hôpital’s Rule instead, we’d first confirm that
lim f (n) = lim g(n) = +∞
n→+∞ n→+∞
l’Hôpital’s rule can be used to compute the limit we need to check to decide whether g ∈ O(f ):
g(n) g 0 (n)
lim = lim
n→+∞ f (n) n→+∞ f 0 (n)
2n
= lim
n→+∞ 1
= +∞,
so that the above “Negative Limit Test for O(f )” (Theorem 6.13) can be used to conclude that
g 6∈ O(f ).
The next example (Example 6.10, in which f (n) = 3 + sin n and g(n) = 1) illustrates that it’s
sometimes necessary to use the definition (or something else that’s different from the limit test):
It’s been shown above, using the definition directly, that f ∈ O(g). However, this can’t be proved
using the limit test, because the necessary limit
f (n)
lim = lim 3 + sin n
n→+∞ g(n) n→+∞
doesn’t even exist! It “doesn’t exist” because there are infinitely many of the values
3 + sin 0, 3 + sin 1, 3 + sin 2, 3 + sin 4, 3 + sin 5, . . .
that are close to 2 (because they correspond to integers n such that sin n is close to −1), but there
are also infinitely many of the above values that are close to 4 (corresponding to integers n such
that sin n is close to +1) — the ratio f (n)/g(n) doesn’t converge to anything at all.
The desired limit
f (n)
lim
n→+∞ g(n)
also doesn’t exist in the final example, Example 6.11, in which f (n) = n2 and in which g(n) = n
when n is odd and g(n) = n3 when n is even. It was argued above that f 6∈ O(g) and g 6∈ O(f ) for
this example.
Perhaps the most important thing to remember about the last two examples is that they show
that you can’t conclude either that f is, or is not, in O(g) when the limit tests fail — more
precisely, you can’t decide whether f ∈ O(g) or not, if the limit tests both fail because the desired
limit doesn’t exist.
71
6.5 Big-Omega Notation
The next notation is probably not familiar to you; it’s similar to “big Oh” notation, but it can be
used to express asymptotic lower bounds (rather than upper bounds) for growth functions.
Informally, f is in big-Omega of g (“f ∈ Ω(g)”) if f grows asymptotically at least as quickly
as g.
Definition 6.14. If f and g are asymptotically positive functions then f ∈ Ω(g) if there exist
constants c > 0 and N ≥ 0 such that
for every integer n ≥ N , f (n) and g(n) are both defined, and f (n) ≥ c · g(n).
Note that the only difference between this and Definition 6.6 (for “f ∈ O(g)”) is the direction
of the inequality at the end.
Examples
You can sometimes prove that f ∈ Ω(g) by using the definition directly, just like you can when
trying to prove that f ∈ O(g).
Suppose, as in Example 6.8, that f (n) = 2n + 10 and g(n) = n. Then if you choose c = 2 and
N = 1, then the condition given in the definition (“f (n) ≥ cg(n) whenever n ≥ N ”) is satisfied, for
this choice of c and N .
Note, by the way, that you definitely couldn’t use the same pair of constants to try to prove
that f ∈ O(g) by using Definition 6.6, even though f ∈ O(g) as well.
You should be able to use the above definition to establish that f ∈ Ω(g) for all but two of the
pairs of functions f and g that have been used as examples in the previous section.
In particular, f 6∈ Ω(g) for the third example, Example 6.9, f (n) = n and g(n) = n2 , and for
Example 6.11, when f (n) = n2 and g(n) = n if n is odd and g(n) = n3 if n is even. In these
cases, you can establish these negative results by assuming that f ∈ Ω(g) and then deriving a
contradiction (like the fact that a constant is strictly less than itself, as in the examples above).
On the other hand, g(n) = n2 ≥ n = f (n) whenever n ≥ 1, so you can choose N = 1 and c = 1
and establish that g ∈ Ω(f ), for Example 6.9, by using the above definition.
Recall that it’s already been established that f ∈ O(g) but g 6∈ O(f ), for this pair of functions;
what does this suggest to you about the relationship between the conditions “f ∈ O(g)” f ∈ Ω(g)”
that have been given so far?
Theorem 6.15 (Limit Test for Ω(f )). If f and g are asymptotically positive functions and
f (n)
lim
n→+∞ g(n)
exists and is either +∞ or is a positive constant (that is, strictly greater than 0), then f ∈ Ω(g).
There’s also a “negative” version that’s useful when the limit is defined, but doesn’t have the
value you want:
72
Theorem 6.16 (Negative Limit Test for Ω(f )). If f and g are asymptotically positive func-
tions and
f (n)
lim =0
n→+∞ g(n)
then f 6∈ Ω(g).
The proofs of these theorems resemble the proofs of Theorems 6.12 and 6.13, and use the
definition of limit (Definition 3.1). Consider trying to prove these theorems, if you want to exercise
your theorem proving skills or test your understanding of the definitions.
Examples
Once again, consider the five examples that have been used so far in this chapter.
If f (n) = 2n and g(n) = n (Example 6.7), then cancellation of a common factor can be used to
compute the desired limit, as shown above, to establish that
f (n)
lim = 2.
n→+∞ g(n)
Since this is a positive constant, this implies that f ∈ Ω(g) in this case.
It’s been shown above that if f (n) = 2n + 10 and g(n) = n (as in Example 6.8) then
f (n)
lim =2
n→+∞ g(n)
In this case, the negative limit test can be used to conclude that f 6∈ Ω(g).
On the other hand, it’s been observed already that
g(n)
lim = +∞
n→+∞ f (n)
for this pair of functions — so that the limit test for Ω(f ) can be used to establish that g ∈ Ω(f )
in this case.
It’s been noted already that if f (n) = 3 + sin n and g(n) = 1 as in Example 6.10 then the limit
f (n)
lim
n→+∞ g(n)
doesn’t exist, so that both the limit test and negative limit test for Ω(f ) “fail.” On the other hand,
since 2 ≤ f (n) ≤ 4 for every integer n, f (n) ≥ 2g(n) for every nonnegative integer n, so you can
use the definition for Ω(f ), with constants c = 2 and N = 0, to prove directly that f ∈ Ω(g) in this
case.
In the final example, Example 6.11, in which f (n) = n2 and g(n) is either n or n3 , depending
on the parity of n, the desired limit doesn’t exist and f 6∈ Ω(g).
Thus, the limit tests are “inconclusive” if the desired limit doesn’t exist — that is, it’s possible
that f really is in Ω(g) in this case, even though the limit of the ratio f (n)/g(n) doesn’t exist, and
therefore can’t be used to prove it — but it’s also possible that f 6∈ Ω(g), as well.
73
6.6 Big-Theta Notation
Informally, f is in big-Theta of g (“f ∈ Θ(g)”) if f grows asymptotically at the same rate as g.
Definition 6.17. If f and g are asymptotically positive functions then f ∈ Θ(g) if and only if
f ∈ O(g) and f ∈ Ω(g). This is the case if and only if there exist positive constants cL , cU > 0 and
N ≥ 0 such that
for every integer n ≥ N , f (n) and g(n) are both defined, and cL g(n) ≤ f (n) ≤ cU g(n).
Note that the final version of the definition (the equivalent condition) is essentially what you
get by combining the two definitions of “f ∈ O(g)” and “f ∈ Ω(g)” (that is, combining all their
requirements together).
Since f ∈ Θ(g) if and only if f ∈ O(g) and f ∈ Ω(g), it should be clear that you can prove that
f ∈ Θ(g) by proving that f ∈ O(g) and then proving that f ∈ Ω(g) as well — and you can prove
that f 6∈ Θ(g) either by proving that f 6∈ O(g) or by proving that f 6∈ Θ(g).
Theorem 6.18 (Limit Test for Θ(f )). If f and g are asymptotically positive functions and
f (n)
lim
n→+∞ g(n)
exists and is a finite constant that is strictly greater than zero, then f ∈ Θ(g).
Note that the above condition on the limit is, essentially, a requirement that it passes both of
the “limit tests” that have been given already for O(f ) and Ω(f ).
Theorem 6.19 (Negative Limit Test for Θ(f )). If f and g are asymptotically positive func-
tions and
f (n) f (n)
either lim = 0 or lim = +∞
n→+∞ g(n) n→+∞ g(n)
then f 6∈ Θ(g).
The above condition on the limit is, essentially, that it satisfies one of the two conditions given
in the “negative limit tests” that have been given so far.
In Examples 6.7 and 6.8, the limit test can be used to prove that f ∈ Θ(g). The negative limit
test can be used to prove that f 6∈ Θ(g) in Example 6.9. The last two examples show that nothing
can be concluded if the above limit doesn’t exist — note that f ∈ Θ(g) in Example 6.10 while
f 6∈ Θ(g) in Example 6.11.
74
Definition 6.20. If f and g are asymptotically positive functions then f ∈ o(g) if for every positive
constant c > 0, there exists a constant N ≥ 0, such that f (n) and g(n) are both defined and
f (n) ≤ cg(n) for every integer n ≥ N .
Note the difference in the way the constants c and N are used here: This is a condition that
must hold for every choice of the positive multiplier c (no matter how small) — and N is allowed
to depend on (that is, be a function of) the multiplier c that is being considered. In general, N
gets larger as c gets smaller.
There is a major difference between this limit test and all the earlier ones: It’s necessary for
the limit to exist, and for it to be equal to zero, in this case, if f ∈ o(g).
Since both the definition and the limit test involve asymptotically positive functions — meaning
that you can rely on the fact that f (n)/g(n) is defined, and positive, for sufficiently large n — this
is actually a reasonably easy theorem to prove: In this case, the condition given above (for it to be
true that f ∈ o(g)) is virtually identical to the condition that
f (n)
lim = 0,
n→+∞ g(n)
as given in Definition 3.1.
If f and g are as defined in Example 6.9 then either Definition 6.20 or the limit test given in
Theorem 6.21 can be used to prove that f ∈ o(g). If f and g are as in Examples 6.7 or 6.8 then
f 6∈ o(g) because the desired limit exists but has the wrong value. Finally, if f and g are as in
Examples 6.10 or 6.11 then f 6∈ o(g) because the desired limit doesn’t exist at all.
75
Again, existence of the limit, and the fact that it is +∞, is a necessary (as well as sufficient)
condition here.
If f and g are as defined in Example 6.9 then g ∈ ω(f ). The limit test can used to prove that
f 6∈ ω(g) for each of Examples 6.7 – 6.11, because the desired limit either has the wrong value or
doesn’t exist at all in each case.
Fact 6.24. A polylogarithmic function grows asymptotically more slowly than any fixed (positive)
power of n. That is, if c is any constant and ² > 0 is also any constant then
no matter how large c is, and no matter how small ² is (as long as ² is positive). This is true, no
matter what (constant) base of the logarithm is used.
Fact 6.25. A polynomial of degree d1 grows asymptotically more slowly than a polynomial of
degree d2 whenever d1 < d2 . In particular, for all constants d1 and d2 ,
Fact 6.26. A polynomial grows asymptotically more slowly than an exponential function whose
base is strictly greater than one. In particular, for every constant d and for every positive constant
² > 0,
nd ∈ o((1 + ²)n ),
no matter how large d is and no matter how small ² is (as long as ² is strictly greater than zero).
76
for A1 to be faster than A2 . You might also try to discover whether the “worst case” is atypical,
or whether it’s close to the “average case” as well.
In the second case (you know that f1 ∈ O(f2 ) and not that f1 ∈ o(f2 )), you could perform a
more careful analysis, in order to determine what the above constant c really is. The result isn’t
very interesting if c is large, and you can’t really consider A1 to be superior based on the above
results unless c < 1.
These applications of asymptotic notation to algorithm analysis motivate the attention being
paid to asymptotic notation in CPSC 413. This will be continued in the next two chapters, in
which we’ll see ways to compute worst case running times of algorithms from their source code or
pseudocode. We’ll also see a bit about how you can perform the “more careful analysis” that’s
mentioned above.
6.10 Exercises
1. Rank the following functions of n by order of asymptotic growth. That is, reorder them
as g1 , . . . , g12 so that gi ∈ O(gi+1 ) for 1 ≤ i ≤ 11. Then, say whether gi ∈ Θ(gi+1 ), for
1 ≤ i ≤ 11, as well. It is not necessary to give proofs for any of your claims.
³ ´n ³ ´n
(a) ln ln n (e) 32 (i) 23
(b) n2n (f) en n2
(j) p
(c) n! (g) ln n (k) log2 n
n
(d) 1000000 (h) 2(1.01 ) (l) log2 n
√
2. Prove that n(ln n)2 ∈ O(n n).
5. Using only the definition of “O(f )” (for an asymptotically positive function f ), prove that
n4 + 3n2 + 8n + 100 ∈ O(n4 ).
(a) For all asymptotically positive functions f and g, either f ∈ O(g), g ∈ O(f ), or both.
(b) For all asymptotically positive functions f and g, either f ∈ O(g), f ∈ Ω(g), or both.
(c) For all asymptotically positive functions f and g, if f ∈ O(g) and f ∈
/ Θ(g), then
f ∈ o(g).
(d) For all asymptotically positive functions f and g, f ∈ O(g) if and only if g ∈ Ω(f ).
(e) For all asymptotically positive functions f , g, and h, if f ∈ O(g) and g ∈ O(h), then
f ∈ O(h).
(f) For all asymptotically positive functions f , g, and h, if f ∈ O(h) and g ∈ O(h), then
f + g ∈ O(h).
Hints for selected exercises are given in the next section; solutions for Exercises #2, 4, 5, 6(a),
6(c), 6(d), and 6(f) can be found in Section 11.1.1.
77
6.11 Hints for Selected Exercises
Exercise #1: You should be able to use the “rules of thumb” given in Section 6.8 to do quite a
bit of the work needed to classify these functions — these should be enough to split the functions
into three or four sets, such that every function in one set grows asymptotically faster than every
function in another.
After that, you should try to use limit tests and (if necessary) the definitions of O(f ), et cetera,
to complete the question. Be prepared to use cancellation and l’Hôpital’s rule in combination (and
possibly, more than once each) to evaluate the limits you obtain.
Note that pictures can be misleading: You should only use them to try to gain intuition, and
you should use the rules of thumb, limit tests, and definitions from this chapter, instead of pictures,
in order to prove things about the asymptotic rates of growth of functions.
Exercises #2–4: Choose an appropriate limit test and then apply it. Be prepared to use can-
cellation or l’Hôpital’s rule to compute the limit you need.
Exercise #6: Some of these claims are true, and some are false.
Since they all describe properties of all pairs (or triples) of asymptotically positive functions,
it’s sufficient to give one pair (or triple) of such functions that don’t have the stated property, in
order to prove that a claim is false. Consider the five examples that were used in this chapter when
looking for this kind of “counterexample.”
On the other hand, you’ll need to use the definitions that were given in this chapter in order to
prove that some of these claims are true.
78
6.12.1 Class Test for 1996
Instructions:
Attempt all questions. Write answers on the question sheets.
No aids allowed.
Duration: 50 minutes.
1. (5 marks — 1 mark for each part) For any pair of functions f (n) and g(n), exactly one of the
following six claims is correct.
For each of the following pairs of functions f (n) and g(n) say which one of these claims is
correct. You do not need to prove your answer.
1.5n
(e) f (n) = n1000 , g(n) = n2
Answer:
3. (10 marks — 5 marks for each part) Say whether each of the following claims is true or false,
and prove your answer.
(a) For every function f such that f (n) is defined and f (n) > 0 for all n ∈ N, f ∈ Θ(f ).
(b) For all functions f and g such that f (n) and g(n) are defined for all n ∈ N, and f (n) and
g(n) are strictly greater than 0 whenever n ≥ n0 for some integer n0 (so that f and g
are asymptotically positive), if f ∈ Ω(g) then f ∈ ω(g).
79
6.12.2 Class Test for 1997
Instructions:
Attempt all questions. Write answers on the question sheets.
No aids allowed.
Duration: 50 minutes.
1. (6 marks — 1 mark for each part) For any pair of functions f (n) and g(n), exactly one of
the following six claims is correct. (However, each claim might be true about zero, one, or
several of the following pairs of functions!)
For each of the following pairs of functions f (n) and g(n) say which one of these claims is
correct. You do not need to prove your answer.
1 2
(a) f (n) = 10 n , g(n) = 20n Answer:
1 1000 ,
(f) f (n) = 1000 (ln n) g(n) = n1/1000 Answer:
3. (6 marks) Say whether the following claim is true or false, and then prove your answer.
Claim: For all asymptotically positive functions f and g, if f ∈ o(g) then g ∈ ω(f ).
80
4. Suppose now that you have two algorithms, A and B, that solve the same problem. The worst
case running time of algorithm A (for input size n) is TA (n), and the worst case running time
of algorithm B is TB (n). TA ∈ o(TB ).
(a) (2 marks) Give the definition for the “worst case running time” of an algorithm.
(b) (2 marks) Give the definition for “f ∈ o(g),” for asymptotically positive functions f
and g.
(c) (1 mark) Does the above statement about algorithms A and B imply that algorithm A
will always solve the problem more quickly than algorithm B? That is, this does imply
that algorithm A will solve the problem more quickly than algorithm B, on every possible
input? Your answer should be either “Yes” or “No.”
(d) (3 marks) Say, in your own words, what the the above statement does imply about the
relative performance of the two algorithms. Be as precise as you can (but try to do
something different than just restating your answer for the first parts of this question).
Note: You shouldn’t need more than the rest of this page to give a complete answer for
this question!
81
82
Chapter 7
Summations
7.1 Overview
This chapter (and the chapter that follows) includes techniques for producing bounds on the worst
case running times of programs from their source code or pseudocode. This chapter concentrates
on techniques for analyzing summations, which arise when analyzing programs with loops.
It is expected that CPSC 413 students will know the definitions that are presented here, that
they will be able to write down summations that bound the worst case running times of simple
(nonrecursive) programs with loops from source code or pseudocode (when given sufficient infor-
mation about the cost of individual instructions), and that they will be able to apply the given
techniques to find functions in “closed form” that are either equal to or that bound summations.
Some problems can only be solved if a specific technique is applied, and some techniques give
better estimates than others — so students will also be expected to choose from the given techniques,
based on the problem to be solved.
A set of exercises and sample tests is given at the end of this chapter, and can be used to assess
the above skills.
Some of the techniques introduced in this chapter require mathematical induction, and one of
them involves integration, so it might be helpful to review the material in Chapters 2 and 4 before
attempting the exercises in this chapter.
i := 1
while (i < n) do
j := i
while (j ≥ 1 and A[j] > A[j + 1]) do
temp := A[j]
A[j] := A[j + 1]
A[j + 1] := temp
j := j − 1
end while
i := i + 1
end while
83
This takes an array A of length n (with indices 1, 2, . . . , n) of integers as input and returns A,
with its contents rearranged in nondecreasing order, as output. For now, we’ll consider the length n
of the input of the array to be the “size” of the input for this program, so the time function we’ll
try to derive will be expressed as a function of n.
84
body, for 1 ≤ i ≤ k. Then — if we charge one for each execution of the loop’s test (which isn’t
part of the loop body) as well, then the total number of steps executed by the loop, in this case,
would be
X
k X
k
1+ (1 + T0 (i)) = k + 1 + T0 (i).
i=1 i=1
Of course, we’ve argued already that “T0 (i)” is just 4, so the cost for the above execution of the
loop would really be
X
k
k+1+ 4 = k + 1 + 4k = 5k + 1.
i=1
If you examine the loop itself, you will discover that the number of executions of the loop body
(on some execution of the loop) depends on
• the value of the variable j, at the beginning of the execution of the loop, and
• the relative magnitudes of the contents of the array in positions 1, 2, . . . , j +1 at the beginning
of the execution of the loop.
Since j is decremented every time the loop body is executed and the loop terminates unless the
latest value of this variable is positive, the loop body can’t be executed more than j times (where
I’m referring, here, to the initial value for the variable with name “j”).
The loop body might be executed fewer times than this: Indeed, it might not be executed at all
(when A[j + 1] is smaller than A[j]). However, if A[j + 1] is larger than each of A[1], A[2], . . . , A[j]
then it will be necessary to move A[j + 1] all the way to the front of the array, so that this loop
body can sometimes be executed the maximal number, j, of times.
Thus the worst case running time of this inner loop is 5j + 1.
The outer loop body contains the inner loop as well as two more statements — a first statement,
which defines the value of j to be used when the inner loop is executed (it is set to i), and a final
statement, which increments i. The number of steps used to execute this inner loop body in the
worst case is therefore a function of i, namely
5i + 3.
Now, when the outer loop is executed, it is always executed with the initial value of i set to 1,
and it only terminates when the value of i reaches n. Thus the outer loop body is always executed
exactly n − 1 times, when the (initial) value of i is 1, 2, . . . , n − 1, and (again, including steps for
the execution of the loop’s test), the number of steps used to execute the outer loop in the worst
case is clearly at most
X
n−1 X
n−1
1+ (1 + (5i + 3)) = 1 + (5i + 4)
i=1 i=1
Ãn−1 ! Ãn−1 !
X X
= 1+5· i +4· 1
i=1 i=1
n(n − 1)
= 1+5· + 4(n − 1)
2
5 2 3
= n + n − 3.
2 2
85
Concluding this part of the analysis, we see that the entire program consists of only one initial
statement and this outer loop, so that the number of steps used by the program in the worst case
on an input of size n is clearly at most
5 2 3
n + n − 2.
2 2
Note: It’s stated that the worst running case is at most (rather than, exactly equal to) this value,
because there’s nothing in this analysis that proves that it’s possible for the inner loop to use its
worst case running time, every time it’s executed. You’d need to prove that this can happen, if you
wanted to state that the worst case running time of the outer loop was exactly the function of n
given above.
In fact — in this particular example — the above function really is the worst case running time
for the program, because exactly 52 n2 + 32 n − 2 steps will be used when this program is executed, if
the input array includes n distinct integers and is sorted in decreasing order instead of increasing
order (so that the largest element is originally at the front of the array instead of the back, and
so on). In this case, when the inner loop is used to try to move A[j + 1] into its correct location,
it will always be true that A[j + 1] is smaller than each of A[1], A[2], . . . , A[j], so that it will be
necessary to move A[j + 1] all the way to the front of the array.
When you’re using the kind of analysis method given here (finding worst case running times for
pieces of a program and adding these functions together), you can always safely conclude that the
resulting function is an upper bound for the running time for the whole program, as we did here.
You can’t conclude immediately that it’s also a lower bound for the worst case running time, so you
need to describe an input, of the required size, for which the program really does use the running
time you obtained in your analysis, if you want to conclude that your time function is exact.
It is not always the case that this kind of analysis technique gives results that are “tight;”
sometimes, instead, one can actually manage to prove that parts of a program only exhibit their
“worst case” behaviour very infrequently, so that the worst case running time for the entire program
(which contains these subprograms) is actually much smaller than the above kind of analysis would
suggest.
Proving this kind of thing is not easy, but it has been used successfully to show that some kinds
of dynamic (or “self adjusting”) data structures are, provably, much more efficient than this kind
of analysis would lead you to think. This is definitely beyond the scope of this course, but you’ll
find some material about this in Chapter 18 (“Amortized Analysis”) of Cormen, Leiserson, and
Rivest [3], in case you’re interested in this.
The topic, “Amortized Analysis,” is sometimes included in CPSC 517.
Another Note: The above analysis is far more detailed than similar ones that you’ll see in the
rest of CPSC 413; we won’t generally worry so much about the multiplicative constants, and will
generally be content, instead, with an asymptotic result — in this case, the result that the worst
running time is in Θ(n2 ) would be sufficient.
This kind of asymptotic result (“Θ(n2 )”) is generally easier to obtain than the derivation of a
more exact worst case running time function. Indeed, we won’t always be able to obtain more than
an asymptotic result, if we want to express the time function in a usable form (namely, in “closed
form,” as described below).
Final Note: As the above example should indicate, summations are obtained when you develop
worst case running times for programs that include while (or, repeat or for) loops.
However, these functions aren’t particularly useful — not readable, and hard to compare to
other running times — if they’re left in this form.
86
7.3 Expressions in Closed Form
Definition 7.1. An expression is in closed form if it contains only a fixed number of
• constants and variables,
for constants a and b (that is, for constants or functions a and b that don’t depend on the index of
summation, i).
Theorem 7.3 (Closed Form for an Arithmetic Series). The arithmetic series
X
n
(a + bi)
i=1
87
has closed form
n(n + 1)
na + b .
2
That is,
X
n
n(n + 1)
(a + bi) = na + b
i=1
2
because there are no terms in the sum to be added together. On the other hand,
n(n + 1)
na + b =0·a+b·0=0
2
as well, when n = 0, so that the identity is correct in this case.
Inductive Step: We now need to prove that if
X
n
n(n + 1)
(a + bi) = na + b
i=1
2
then
X
n+1
(n + 1)(n + 2)
(a + bi) = (n + 1)a + b ,
i=1
2
X
n+1 X
n
(a + bi) = (a + bi) + (a + b(n + 1))
i=1 i=1
n(n + 1) 2(n + 1)
= (n + 1)a + b +a+b
2 2
(n + 2)(n + 1)
= (n + 2)a + b
2
(n + 1)(n + 2)
= (n + 2)a + b ,
2
88
as desired. Since the integer n ≥ 0 was arbitrarily chosen it follows that if
X
n
n(n + 1)
(a + bi) = na +
i=1
2
then
X
n+1
(n + 1)(n + 2)
(a + bi) = (n + 1)a +
i=1
2
CPSC 413 students certainly should be able to prove the above theorem, since it only requires
a straightforward use of mathematical induction. In practice, though, this won’t be necessary —
it’ll be sufficient to recognize that a given summation is an arithmetic series and then just to state
and use the above closed form.
Recall, by the way, that summation is “linear.” That is, for any constants c, d (or functions
that don’t depend on i) and functions f and g,
à n ! à n !
X
n X X
(cf (i) + dg(i)) = c f (i) + d g(i) ,
i=1 i=1 i=1
so, in particular,
à n ! à n !
X
n X X
(a + bi) = a 1 +b i ,
i=1 i=1 i=1
and you should be able to derive the closed form for an arbitrary arithmetic series, as long as you
can remember that
X
n X
n
n(n + 1)
1=n and i= .
i=1 i=1
2
Finally, you should note that an arithmetic series was recognized and its closed form was used
in the example given in Section 7.2.
where a and r are constants (or functions that don’t depend on i) and r 6= 1.
Theorem 7.5 (Closed Form for a Geometric Series). The geometric series
X
n
ari−1
i=1
89
has the closed form
rn − 1
a .
r−1
That is,
X
n
rn − 1
ari−1 = a
i=1
r−1
Note that (using linearity) you should be able to derive this for any choice of a, as long as you
can remember the closed form when a = 1,
X
n
rn − 1
ri−1 = .
i=1
r−1
Once again CPSC 413 students certainly should be able to prove the above theorem — it only
requires mathematical induction — but this won’t be necessary in practice. Instead, it’s sufficient
to recognize that a given series is a geometric series, and then state and apply the closed form for
it without proving it.
where f is a function of i.
Theorem 7.7 (Closed Form for a Telescoping Sum). If the function f is given by an expres-
sion in closed form, then the telescoping sum
X
n
(f (i − 1) − f (i))
i=1
f (n + 1) − f (1).
That is,
X
n
(f (i + 1) − f (i)) = f (n + 1) − f (1)
i=1
90
Yet again, CPSC 413 students should be able to theorem is correct but will only be expected
to apply it, without proof, in practice.
Sometimes telescoping sums will be “disguised” — you may (only) be able to express them in
the above form by performing some algebraic manipulations on what you’ve been given.
Suppose, for example, that you want to find
X
n
1
.
i=1
i2 + i
At first glance it might not be clear what to do. However, it is possible to rewrite this sum in a
form that allows us to use the above closed form to solve it:
X
n
1 X
n
1
= (f (i + 1) − f (i)), for f (i) = − .
i=1
i2 + i i=1 i
for some particular function g and some unknown constants c1 , c2 , . . . , cl . Frequently the above
expression is linear in c1 , c2 , . . . , cl (and this is the easiest case to deal with).
In such a case, you can often make progress as follows.
1. Consider the values of the summation for small values of n (n = 1, 2, . . . , l will often be
sufficient if there are l unknown constants) — that is, compute each of these values.
2. Use these values, along with the above general expression “g(c1 , c2 , . . . , cl , n), to form a sys-
tem of equations in the unknown values c1 , c2 , . . . , cn . If the above expression is linear in
c1 , c2 , . . . , cn , then the resulting system will be a system of linear equations, so that you can
use Gaussian Elimination to perform the next step:
4. Plug the values you obtained for c1 , c2 , . . . , cn into the original expression to produce a closed
form for the given summation that’s a function of n.
5. Use mathematical induction on n to confirm that the closed form you’ve derived really is
correct.
91
Suppose, for example, that you forgot the formula for an arithmetic series, but you remembered
that
X
n
i
i=1
X
2
i = 1 + 2 = 3,
i=1
and
X
3
i = 1 + 2 + 3 = 6,
i=1
c0 + 1 · c1 + 1 · c2 = 1
c0 + 2 · c1 + 4 · c2 = 3
c0 + 3 · c1 + 9 · c2 = 6.
This system can be solved using Gaussian Elimination, to discover that c0 = 0 and c1 = c2 = 12 ,
suggesting that
X
n
1
i = c0 + c1 n + c2 n2 = (n2 + n).
i=1
2
In order to complete this example, you should use mathematical induction on n to confirm that
this formula really is correct, for every integer n ≥ 1.
Here is a variation on this technique: Sometimes you might guess a closed form for a summation
after checking its value for small values of n, without being told what form it takes ahead of time.
92
If your guess is correct, then you may be able to prove this by using induction on n.
For example, rather than writing
X
n
1
S(n) =
i=1
i2 +i
as a telescoping sum (as above), you might evaluate this at small values, noting that
1 2 3 4
S(1) = , S(2) = , S(3) = , S(4) = , . . .
2 3 4 5
and “guess” at around this point that S(n) = n+1 n
for every integer n ≥ 1.
Of course you wouldn’t have proved it at this point (and you might even guess incorrectly),
but, in this case (since the guess is correct) you could then prove that your answer is correct by
using mathematical induction on n.
for two families of functions of x, f1 (x), f2 (x), . . . and g1 (x), g2 (x), . . . . Recall that a linear operator
L (on functions) maps functions to functions in such a way that
for any functions h1 (x) and h2 (x) and for any constants c1 and c2 .
Then you can apply the operator L to both sides of equation (7.1), above. Since the operator L
is a linear operator and the expression on the left hand side of the equation is a sum of a finite
number of terms (for any fixed n), you can correctly conclude that
à n !
X
n X
L(fi (x)) = L fi (x) = L(gn (x)).
i=1 i=1
There are two linear operators on functions that you might use employ here to solve new summations
from old ones: differentiation and definite integration.
7.6.1 Differentiation
The operator
is a linear operator, and you can use this with any equation
X
n
fi (x) = gn (x)
i=1
93
to conclude that
X
n
fi0 (x) = gn0 (x)
i=1
as well.
Suppose, for example, that we start with the fact that
X
n
xn − 1
xi−1 = ;
i=1
x−1
this is the closed form for a geometric series (such that the “ratio” r mentioned in the definition
for a geometric series happens to be the variable x).
This matches the above form, when fi (x) = xi−1 for 1 ≤ i ≤ n and
xn − 1
gn (x) = .
x−1
In this case, fi0 (x) = (i − 1)xi−2 for 1 ≤ i ≤ n and
(x − 1)(nxn−1 ) − (xn − 1)(1) (n − 1)xn − nxn−1 + 1
g 0 (n)(x) = = .
(x − 1)2 (x − 1)2
Therefore, we can apply this method to conclude that
X
n
(n − 1)xn − nxn−1 + 1
(i − 1)xi−2 = .
i=1
(x − 1)2
If we multiply both sides of the above identity by x, we have that
X
n
(n − 1)xn+1 − nxn + x
(i − 1)xi−1 = .
i=1
(x − 1)2
If we denote i − 1 by j then we have that
X
n−1
(n − 1)xn+1 − nxn + x
jxj = .
j=0
(x − 1)2
Now, replace n − 1 by m:
X
m
mxm+2 − (m + 1)xm+1 + x
jxj = .
j=0
(x − 1)2
Since 0x0 = 0, so that the first term of the sum doesn’t contribute anything to it, it’s also true
that
X
m
mxm+2 − (m + 1)xm+1 + x
jxj = .
j=1
(x − 1)2
Finally, let’s replace j by i and m by n, just so that we’re always using the same variables for
the index of summation and the number of terms; then we have that
X
n
nxn+2 − (n + 1)xn+1 + x
ixi = .
i=1
(x − 1)2
If you’d like to check this derivation (just to be sure that no arithmetical errors have been
made), then you can use induction on n to prove that this last identity is correct.
94
7.6.2 Definite Integration
The operator
Z x
L(f (x)) = f (t) dt
0
is also a linear operator, and you can use this with any equation
X
n
fi (x) = gn (x)
i=1
to conclude that
n µZ
X x ¶ Z x
fi (t) dt = gn (t) dt
i=1 0 0
as well.
While the last statement is correct, it can sometimes be difficult to use this to find closed forms
for summations: You need to be able to find closed form expressions for the integral given here on
the right hand side, in order to make this work.
The remaining methods can be used to find asymptotic bounds for summations, rather than
expressions that are equal to them. It’ll often be necessary to use several of them in combination.
because there are n − m + 1 terms in the sum and each has a value that’s between l and U .
This holds, for example, if
then
so that the above inequality can be written in a simpler form (or, at least, one that involves no
unknowns):
95
Theorem 7.8. If m < n and f is nondecreasing then
X
n
(n − m + 1) · f (m) ≤ f (i) ≤ (n − m + 1) · f (n).
i=m
Since the function f (n) = log2 n is nondecreasing, the above theorem can be used. Since log2 1 = 0,
it can be used to conclude that
X
n
0≤ log2 i ≤ n log2 n.
i=1
As the above example should suggest, the previous technique isn’t generally enough to give (prov-
ably) tight asymptotic bounds for summations by itself. It often works better along with the
observation that if m is any integer between 1 and n then
X
n X
m X
n
f (i) = f (i) + f (i),
i=1 i=1 i=m+1
so that if
X
m
l1 ≤ f (i) ≤ U1
i=1
and
X
n
l2 ≤ f (i) ≤ U2
i=m+1
then
X
n
l 1 + l2 ≤ f (i) ≤ U1 + U2 .
i=1
96
once again, and let m = b n2 c. Consider again the lower bounds you’d obtain for pieces of this
summation. Since f (x) = log2 x is a nondecreasing function (at least, over the positive reals),
X
m
log2 i ≥ m · log2 1 = 0,
i=1
which is no more helpful than before; however, the approach of “bounding terms” can also be used
now to conclude that
X
n
log i ≥ (n − (m + 1) + 1) log2 (m + 1)
i=m+1
= (n − m) · log2 (m + 1)
¡ ¢ ¡ ¢
= n − b n2 c · log2 1 + b n2 c
¡n¢ ¡ ¢
≥ 2 · log2 2
n
2 · (log2 n −
n
= log 2)
≥ 1
4 n log2 n
as well. Combined with the upper bound obtained above, by bounding terms for the original sum,
this implies that
X
n
log2 i ∈ Θ(n log2 n).
i=1
97
changing perspective (and considering the case for i + 1 as well),
Z i Z i+1
f (t) dt ≤ f (i) ≤ f (t) dt,
i−1 i
if f is defined and nondecreasing on the set of real numbers between i − 1 and i + 1. Now, since
Z n n Z
X i
f (t) dt = f (t) dt
0 i=1 i−1
and
Z n+1 n Z
X i+1
f (t) dt = f (t) dt,
1 i=1 i
by applying the above theorem and computing the definite integrals that it mentions.
This approach has the disadvantage of needing integration; it often has the advantage that it
gives much better approximations than the last few methods that have been discussed.
For example, this method can be used to derive a much tighter approximation for the summation
X
n
log2 i
i=1
Now, since
ln n
f (n) = log2 n = = (log2 e) ln n
ln 2
98
is defined and is nondecreasing on the set of real numbers between 1 and n + 1, we can conclude
from the above theorem that
Z n X
n Z n+1
(log2 e) ln t dt ≤ log2 i ≤ (log2 e) ln t dt.
1 i=2 2
Z n+1 Z n+1
(log2 e) ln t dt = (log2 e) ln t dt
2 2
= (log2 e)((n + 1) ln(n + 1) − (2 ln 2 − 2))
≤ (log2 e)(n + 1) ln(n + 1) + (log2 e)
≤ (log2 e)(n + 1) ln(ne)
whenever n ≥ 3, and
implying that
X
n
(log2 e)n ln n − (log2 e)n + log2 e ≤ log2 i ≤ (log2 e)n ln n + (log2 e)n + (log2 e) ln n + log2 e
i=1
Since (log2 e)n ln n ∈ ω(n), this means that we really have improved on the estimate for the sum
that we’d obtained before, by approximating it so that the error in the approximation is sublinear
in the value of the sum itself.
99
for functions f and g, one can generally proceed by developing two proofs by mathematical induction
— one being that
X
n
f (i) ≤ cg(n)
i=1
for every integer n ≥ 1, for some unknown positive constant c, which implies that the sum is in
O(g), and the other being that
X
n
f (i) ≥ ĉg(n)
i=1
for every integer n ≥ 1, and for some other unknown positive constant ĉ which implies that the
sum is in Ω(g).
In the process of trying to develop these proofs you generally discover conditions (frequently,
inequalities) that the unknown constants c and ĉ must satisfy. Once you’ve developed these proofs,
you can frequently choose specific constants c and ĉ that satisfy all these conditions. You can then
observe that you can “plug these constants” into the proofs you’ve developed and that the proofs
remain valid. Once you’ve done all that, you can conclude that
X
n
f (i) ∈ Θ(g(n)),
i=1
as desired.
Suppose, once again, that you want to use the fact that
X
n
i ∈ Θ(n2 )
i=1
but that you don’t want (or need) to find an exact representation of the summation in closed form.
According to the argument given above, you’d first try to prove by induction on n that
X
n
i ≤ cn2
i=1
this is also satisfied if c ≥ 1, as you could confirm by comparing the coefficients of 1, n, and n2 in
the leftmost and rightmost expressions shown here.
At the end of this you could therefore choose c = 1 (or, if you wanted to, c = 2, etc.), and then
go back and confirm that the proof remains correct for your specific choice of c.
To derive a lower bound you’d repeat the process, trying to prove by induction on n that
X
n
i ≥ ĉn2
i=1
100
for every integer n ≥ 1 and for some unknown constant ĉ.
In this case, you would probably discover that you need to assume that ĉ ≤ 1 in order to
complete the basis, but also that you want to assume that ĉ ≤ 12 in order to (easily) complete the
inductive step.
Choosing ĉ = 12 (or, if you want to, ĉ = 13 , etc.), you could go back over the proof and confirm
that it remains correct for your choice of ĉ.
Having proved that
1 2 X n
n ≤ i ≤ n2
2 i=1
T (n) ≤ cg(n)
T (n) ≥ ĉg(n)
for all (sufficiently large) n, for some “unknown” positive constant ĉ. The process that you follow
after completing this proof is the same as the process you follow after completing the proof that
involved the constant c, when you were trying to establish that T (n) ∈ O(g(n)).
When you develop the proofs involving “unknown constants” that are described above you
must treat the unknown values as constants — things that (each) have one fixed value that
is unchanged, throughout the proof. Otherwise, you will not be able to choose one value for
the unknown, at the end of the process, and you won’t be establish the conclusion (namely, the
asymptotic bound) that you wanted to.
Unfortunately, one reasonably common error that students make in this process is to treat the
unknown whose something whose value can “shift” or “change” throughout the proof.
Here is an example of a false claim and a fallacious proof of the claim. The only technical
error that is made in this proof is the error that has just been described.
101
False Claim: If
X
n
T (n) = 1
i=1
Fallacious Proof: It will be proved by induction on n that T (n) ≤ c for some unknown constant c,
for every integer n ≥ 0.
Basis: If n = 0 then T (n) = 0, so T (n) ≤ c in this case provided that c ≥ 0.
Inductive Step: Suppose that n ≥ 0 and that T (n) ≤ c.
Then
X
n+1
T (n + 1) = 1 by the definition of T
i=1
à n !
X
= 1 +1 splitting the sum
i=1
X
n
= T (n) + 1 since T (n) = 1
i=1
≤c+1 by the inductive hypothesis
≤ ĉ for ĉ = c + 1.
T (n) ≤ c
T (n + 1) ≤ c
T (n + 1) ≤ ĉ,
for a different constant ĉ — because the fact that T (n + 1) ≤ ĉ does not imply that T (n + 1) ≤ c,
as well.
Let’s think about what’s really been “proved,” above: If you take the proof, and think about
what it implies about the values T (0), T (1), T (2), and so on, then you should discover that it
establishes, only, that
102
2. T (1) ≤ c1 , for some value c1 ≥ 1;
103
7.12 Exercises
1. Find expressions in closed form that are equal to each of the following summations.
X
n
(a) (4i + 5)
i=1
Xn
(b) 5i
i=1
Xn
(c) sin(i + 1) − sin i
i=1
Xn
i
(d)
i=1
(2i + 1)2 (2i − 1)2
and prove that it is correct, starting only with the information that it is a polynomial function
of n with degree three.
3. Find asymptotically tight bounds in closed form for each of the following summations. That
X
n
is, for each function f (i), try to find an expression g(n) in closed form such that
i=1
X
n
f (i) ∈ Θ(g(n)).
i=1
As time permits, you should try to apply several (or even all) of the techniques that were
introduced in class in order to solve these problems, in order to gain practice using these
techniques, and you should compare the answers that you get using them. Note, though, that
some of the techniques might not be applicable in all cases, and others might be difficult to
apply.
X
n
(a) i3
i=1
Xn
(b) i4 ln i
i=1
X
n
1
(c)
i=1
i
Xn
1
(d)
i=1
i2
X
n
(e) (i!) ln i
i=1
104
4. Prove that
X
n
i2 ∈ Θ(n3 )
i=1
without solving the summation exactly. That is, try to complete the pattern suggested above
in order to prove an asymptotic bound, rather than doing Question 2 all over again.
5. It was shown in this chapter that you could approximate a summation of a nondecreasing
function by integrals. Find (and prove correct) a similar approximation of a nonincreasing
function instead.
Then, try to apply this (where appropriate) to improve your answers for Question 3, above.
Hints for selected exercises are given in the next section; solutions for Exercises #1(d), 3(b)
and 4 can be found in Section 11.2.1.
i c c
= − ;
(2i + 1)2 (2i − 1)2 (2i + 1)2 (2i − 1)2
it should be easy to find a closed form for the summation after that.
Exercise #3(c): Observe that the sum of the last half of the terms of this sum is in Θ(1), and try
to use this to prove (using the strong form of mathematical induction) that the sum is in Θ(log2 n).
If you’d like try a different approach then you can observe that
X
n
1 X
n−1
1
= ,
i=1
i j=0
n−j
because the second sum just lists the same terms as the first, in reverse order. Note that the
function
1
f (x) =
n−x
is defined and nondecreasing on the set of real numbers x between 0 and n − 1. You should be able
to use approximation by integrals to estimate the sum, given this information.
105
Now, use the second observation to prove that
X
n
1
∈ Θ(1),
i=1
i2 +i
as well.
Alternatively, you can reverse the order of the terms in the given summation (as in the second
approach suggested above for Exercise #3(c)) to make the sum look like a sum of a nondecreasing
function, and then use approximation by an integral to finish.
Exercise #5: This can be answered by reading, and making small changes to, the derivation
of the approximation of the sum of a nondecreasing function by an integral that’s given in this
chapter.
X
n
1. (10 marks) Find a function f (x) (in closed form) such that i4 − f (n) ∈ O(n4 ), and prove
i=1
that your answer is correct.
Note: You may use the fact that the function g(x) = x4 is an increasing function, without
proving it.
X
n
2. (10 marks) Prove that i log2 i ∈ Θ(n2 log2 n).
i=1
106
7.14.2 Class Test for 1997
Instructions:
Attempt all questions. Write answers on the question sheets.
No aids allowed.
Duration: 50 minutes
X
n−1
(a) 3 · 6i
i=0
(1 mark:) This is a
(1 mark:) This is a
2. (1 mark) Briefly explain why you might need to find asymptotic bounds for summations in
closed form, when estimating the worst case running times of programs from source code.
107
Note: You may assume that the function f (x) = x2.5 is a nondecreasing function of x
(defined on the nonnegative reals) without having to prove it.
X
n
i(ln i)3 ∈ Θ(n2 (ln n)3 ).
i=1
There are several ways that you could prove this using techniques introduced in class; each
will be acceptable (provided that the methods are used correctly).
If you get stuck, you can say what you’d need to do in order to finish (even though you
couldn’t manage to do it) in order to earn part marks.
Note: You may assume that the function f (x) = x(ln x)3 is a nondecreasing function of x
(defined on the positive reals) without proving it.
108
Chapter 8
Recurrences
8.1 Overview
This chapter is a continuation of the previous one, in the sense that it includes techniques for pro-
ducing bounds on the worst case running times of programs from their source code or pseudocode.
The previous chapter included techniques for analyzing nonrecursive programs; this one introduces
techniques for the analysis of recursive programs as well.
The chapter includes an introduction to “recurrences,” which often arise when you try to write
down the worst case running time of a recursive program, but which aren’t in closed form, and
it presents several techniques for producing functions in closed form that are either equal to or
asymptotic bounds for functions that are given by recurrences. Some general techniques, that
aren’t always very easy to apply, are presented first. These include a “substitution method” and
an “iteration method,” as well as several techniques for simplifying recurrences. More specific
techniques, that aren’t always applicable at all but that are frequently easier to use when they are
applicable, are presented after that.
As usual, CPSC 413 students will be expected to know the definitions that are presented here.
They will also expected to be able to write down expressions — which may involve both summa-
tions and recurrences — for the worst case running times of programs, when given the programs’
source code or pseudocode. They will also be expected to recognize which of the techniques (being
introduced here) are applicable to a given recurrence, and to be able to apply these techniques in
order to write down functions in closed form that are equal to or that bound these expressions.
A set of exercises and sample tests is given at the end of this chapter, and can be used to assess
the above skills.
Some of the techniques involved in this chapter require mathematical induction, so it might be
helpful to review the material in Chapter 2 before attempting the exercises in this chapter, if you
haven’t already done so.
109
integer function fib (n: integer)
if (n ≤ 0) then
return 0
elsif (n = 1) then
return 1
else
return fib(n − 1) + fib(n − 2)
end if
end function
For the moment, let’s define T (n) to be the number of steps executed by this function on the
input n (we won’t worry about the time used by this a program, defined as a function of input size,
just yet).
Then (using the “unit cost” criterion, as defined in the previous chapter), it seems that
T (n) = 2 if n ≤ 0,
and
T (1) = 3,
provided that we charge one for each test that must be executed, as well as one more step when a
value is returned.
If n ≥ 2, then two tests are executed and fail; the function is then recursively applied — twice
— and then the results are added together and returned. If we charge one step for the final addition
and return of the result, then can conclude that
T (n) = T (n − 1) + T (n − 2) + 3 if n ≥ 2.
• indices i and j, usually such that 1 ≤ i ≤ j ≤ n, but possibly also with j < i
• an integer key that you’re looking for, inside a portion of the array A (namely, the piece in
between positions i and j)
and think of the output as being 0 if key is not in any of the positions i, i + 1, . . . , j, and as being
an integer h such that i ≤ h ≤ j and A[h] = key, otherwise.
110
integer function BSearch(A, i, j, key)
if (i > j) then
return 0
else j k
mid := (i+j)
2
if (A[mid ] = key) then
return mid
elsif (A[mid ] > key) then
return BSearch(A, i, mid − 1, key)
else
return BSearch(A, mid + 1, j, key)
end if
end if
end function
For this case, let’s try to define a function T (m) in terms of an integer m, where m = j − i + 1.
That is, m is the length of the subarray that’s being examined by the above function (put another
way, m is the number of possible locations within the array in which key might be located if it’s
found).
If m ≤ 0 then, necessarily, i > j, so that the function terminates after executing the first test
— which succeeds — and after returning the constant 0. Therefore,
T (m) = 2 if m ≤ 0.
Otherwise, mid is defined to be the “middle” position within the subarray being searched. Since
m = j − i + 1 > 0,
¹ º ¹ º ¹ º
i+j j−i m−1
(mid − 1) − i + 1 = −i= =
2 2 2
and
¹ º » ¼ » ¼
i+j j−i m−1
j − (mid + 1) + 1 = j − = = .
2 2 2
Assuming (correctly!) that T (m) is a nondecreasing function of m, the “worst case” occurs
when A[mid ] < key, sol that
m all the tests executed at the top level of the code fail and the right
m−1
subarray, with length 2 , must be searched. This implies that
³l m´
T (m) ≤ 5 + T m−1
2 if m ≥ 1.
We can’t conclude yet that T (m) is always equal to the expression shown on the right hand side,
above, because we haven’t argued that it’s always possible to design an input including an array of
size m, with a right subarray of size d m−1
2 e, such that the worst case number T (d 2 e) of operations
m−1
will be used to complete the operation of the algorithm on this right subarray (it’s at least plausible
that the algorithm will always be faster than that, at this point during the computation).
However, it is the case that this maximum number of operations can be used at this point. In
particular, it’s possible to prove by induction on m that this maximum number of operations really
will be used, as long as key is strictly greater than every element stored in the array. Therefore,
2 e)
T (m) = 5 + T (d m−1 if m ≥ 1.
111
8.3 Recurrences
Definition 8.1. A recurrence is an equation or inequality that describes a function in terms of its
values on smaller inputs.
An example of a recurrence is the description of the running time function “T (n)” for the
function fib, on input n, that we just derived:
if n ≤ 0,
2
T (n) = 3 if n = 1, (8.1)
T (n − 1) + T (n − 2) + 3 if n ≥ 2.
Another example is the recurrence derived for the number of steps executed by BSearch, defined
as a function of m:
(
2 if m ≤ 0,
T (m) = (8.2)
2 e) + 5
T (d m−1 if m ≥ 1.
Here are two more examples of recurrences; they both describe the function T (n) that was
defined for fib, though neither specifies it exactly:
if n ≤ 0,
3
T (n) ≤ 4 if n = 1, (8.3)
T (n − 1) + T (n − 2) + 3 if n ≥ 2;
if n ≤ 0,
0
T (n) ≥ 1 if n = 1, (8.4)
T (n − 1) + T (n − 2) if n ≥ 2.
The following isn’t a recurrence for T (n), even though T satisfies this definition. It isn’t a
recurrence because the final part of this expresses T (n) in terms of larger as well as smaller values,
and not in terms of smaller values alone:
if n ≤ 0,
2
T (n) = 3 if n = 1,
T (n + 1) − T (n − 1) if n ≥ 2.
It also fails to define T (n) uniquely; you’d add the condition that the last equation is also
satisfied when n = 1 (making it possibly look like you’d “defined” T (2) twice) in order to achieve
this. However, we won’t be worrying about the properties of “non-recurrences” like this one.
Unfortunately, it isn’t always easy to express the worst case running time for a recursive al-
gorithm as a recurrence. However, if the recursive algorithm is reasonably well behaved — if the
size of the input is decreased whenever the algorithm calls itself recursively, or some other function
of the input is decreased whenever this happens (and the algorithm can be proved to terminate
whenever the value of this other function is small) — then one can state the worst case running
112
time for the algorithm as a recurrence, as we did here for the two examples fib and BSearch. We’ll
only look at these “well behaved” kinds of recursive algorithms in CPSC 413.
As before, we’d like to find time functions that are given as expressions in closed form, and
recurrences aren’t in this form. We’ll therefore consider methods to find exact solutions as well as
asymptotic bounds for recurrences that are in closed form.
T (n) ≥ ĉg(n) for every integer n ≥ 0, for some (other!) positive constant ĉ.
As was the case for the previous method, you’ll try to use mathematical induction (on n) to
generate each proof.
In the course of doing this, you’ll identify a number of constraints on the constants c and ĉ that
must be satisfied. At the end of all this (if things work), you should be able to choose constants c
and ĉ that satisfy all of them — and you should also be able to confirm that your proofs are
complete and correct, if you go back and “plug in” these values for the constants.
Finally, in order to prove that
T (n) ∈ Θ(g(n)),
you should try to apply this method twice, once to prove that
T (n) ∈ O(g(n)),
and then again to prove that
T (n) ∈ Ω(g(n)).
When this method was introduced for summations it was noted that a “common mistake”
should be avoided — you should remember to treat c and ĉ as constants whose values you don’t
happen to know yet, and not as variables. It’s just as easy to make this mistake when you’re using
the method to deal with recurrences as it is for summations, and you should review the material
in Section 7.10.1 if this doesn’t seem familiar.
113
8.4.2 Application to an Example
Suppose you are given the recurrence
1 if n = 0,
T (n) = 1 if n = 1,
T (n − 1) + T (n − 2) if n ≥ 2,
T (n) ∈ O(g(n))
for g(n) as above, and in order to do this you’d try to use induction on n to prove that
³ √ ´n
T (n) ≤ c 1+ 5
2 for every integer n ≥ 0,
so it is necessary and sufficient to choose c to be greater than or equal to 1 in order to satisfy both
of the conditions on c that were identified in the basis.
Inductive Step: Suppose now that n is greater than or equal to 0 and that
T (n + 2) ≤ cg(n + 2)
114
as well.
Now since n ≥ 0, n + 2 ≥ 2, so that
T (n + 2) = T (n + 1) + T (n) by the recursive definition of T ,
³ √ ´n+1 ³ √ ´n
≤c 1+ 5
2 + c 1+2 5 by the inductive hypothesis
³ √ ´n ³ √ ´
= c 1+2 5 · 1+2 5 + 1
³ √ ´n ³ √ ´2
= c 1+2 5 · 1+2 5 by the above hint,
³ √ ´n+2
= c 1+2 5 as required.
Thus the “inductive step” can be completed without adding any additional conditions on the
constant c.
It follows that we can choose c = 1 in order to satisfy all the conditions that were identified in
the basis and the inductive step, proving that
³ √ ´n
T (n) ≤ 1+ 5
2 for every integer n ≥ 0.
• conclude at the end of the basis that it is necessary and sufficient to choose
ĉ ≤ 2√
1+ 5
in order to satisfy all the constraints on ĉ that had been identified at that point.
After doing this, you should have a correct proof that
T (n) ≥ ĉg(n) for every integer n ≥ 0
for some positive constant ĉ ≤ 2√
1+ 5
, and this implies that
T (n) ∈ Ω(g(n)).
Since T (n) ∈ O(g(n)) and T (n) ∈ Ω(g(n)), T (n) ∈ Θ(g(n)), as desired.
115
8.4.3 Application to Another Example
Suppose that you were given a recurrence of the form
if n ≤ 1,
0
T (n) = 1 if n = 2,
T (b n c) + 1 if n ≥ 3.
2
In order to prove that this is the case, using the substitution method, you’d first try to establish
by induction on n that
for some positive constant c. Since the recurrence relates the value of the function on input n to
the value on input b n2 c, rather than on input n − 1, it’ll be most convenient to use the “strong”
form of mathematical induction (namely, the last version of mathematical induction introduced in
Section 2.3). The proof will therefore look something like the following.
Basis: If n = 1 then T (1) = 0, as defined by the above recurrence.
On the other hand, if n = 1 then c log2 n = c log2 1 = 0 as well, regardless of the choice of the
constant c.
So if n = 1 then (since 0 ≤ 0), T (n) ≤ c log2 n for every constant c ≥ 0.
Inductive Step: Suppose, now that n ≥ 1 and that
T (m) ≤ c log2 m
for every integer m such that 1 ≤ m ≤ n. It is necessary and sufficient to prove, using only this
assumption, that
T (n + 1) ≤ c log2 (n + 1)
as well.
Now, since n ≥ 1, n + 1 ≥ 2, and so it follows by the given recurrence for T (n) that
2 c) + 1
T (n + 1) = T (b n+1
³ ´
≤ c log2 b n+1
2 c +1 by the inductive hypothesis, since 1 ≤ b n+1
2 c≤n
³ ³ ´´
≤ c log2 n+1
2 +1 since f (x) = log2 x is increasing, and c > 0
= c log2 (n + 1) − c log2 2 + 1
= c log2 (n + 1) − c + 1
≤ c log2 (n + 1) as required, provided that c ≥ 1.
Now, only one condition on c (apart from the fact that it must be positive) was identified during
this proof, namely, the condition that c ≥ 1 on the last line of the above sequence of equations.
116
Therefore can “choose” c to be any such constant after the fact — we’ll pick c = 1 — and
conclude that
Two things should be noted about the above proof. Note first that we started with n = 1
instead of with n = 0. “By default,” you should generally try to start with n = 0. We’d run into
a problem if we did this here, because we’d need to make an argument about the value of “log2 0”
in order to establish the basis if we did things this way, and of course log2 0 is undefined. Starting
from n = 1, instead, eliminates this problem.
The second noteworthy thing has already been mentioned: We’re using the strong form of
mathematical induction in order to deal with a recurrence which defines T (n) in terms of T (m)
where m is not n − 1 (or n − 2) in all cases; the strong form of induction is useful when dealing
with a recurrence that expresses T (n) in terms of T (m) where m is smaller than n by a constant
factor (rather than having n − m being bounded by a constant), as is the case here.
Next, to prove that T (n) ∈ Ω(log2 n), we should try to prove that
If the recurrence for T had been slightly different — in particular, if it had been
if n ≤ 1,
0
T (n) = 1 if n = 2,
T (d n e) + 1 if n ≥ 3,
2
so it included the ceiling instead of the floor function, then this would have been reasonably
straightforward, in the sense that we could have used the proof given above, after modifying it
by replacing c with ĉ and changing the direction of the inequalities (replacing “≤” with “≥”, and
vice-versa) throughout.
However, we can’t do this, using the recursive definition as originally given, because the resulting
“proof” would depend on the inequality
³ ´ ³ ³ ´´
ĉ log2 b n+1
2 c + 1 ≥ ĉ log2
n+1
2 + 1,
1. Prove that T is a nondecreasing function — that is, that T (n) ≤ T (n + 1) for every integer
n ≥ 1. This will turn out to be straightforward.
117
3. Now, try to prove by induction on k (and not on n) that there exists a positive constant ĉ
such that
that is, prove that the desired inequality holds for T (n) whenever n is a power of two.
You’ll discover now that the “floor” function doesn’t cause a problem, because it will always
be applied to an integer in your proof (that is, it will never have any “effect”), so the proof
would be the same as it would be, if the floor function didn’t appear in the function definition
at all.
In other words, you’ll be taking advantage of the fact that if T̂ is a function defined on the
real numbers by the recurrence
if n ≤ 1,
0
T̂ (n) = 1 if 1 < n ≤ 2,
T̂ ( n ) + 1 if n > 2,
2
then T (2k ) = T̂ (2k ) for every integer k ≥ 0, and it’s reasonably easy to prove that T̂ (n) ≥
log2 x for every real number x > 0 (using induction on dxe).
So, you’ll be able to show that
4. Use the last two things you established to prove that if n ≥ 2 then
The trick used here — establishing that T is a nondecreasing function, proving the desired
inequality for T (n) when n is of a special form, and then combining the two facts to prove a
weaker (but sufficient) inequality for T (n) in the general case — will be discussed in more detail in
Section 8.6.1, below.
As an exercise, you should try to develop a proof that T (n) ∈ Ω(log2 n) by following the given
outline, for T (n) as above. In case you get stuck (or want to compare your proof to mine), a more
complete proof that does follow this outline appears below.
118
Clearly, T (n) ≤ T (n + 1) if n is an integer and n < 0, since T is a constant function on
the negative integers, so it’s only necessary to prove that T (n) ≤ T (n + 1) for every nonnegative
integer n.
We’ll prove this by induction on n, using the strong form of mathematical induction.
Basis: If n = 0 then T (n) = T (0) = 0 and T (n + 1) = T (1) = 0, so T (n) ≤ T (n + 1) in this case.
Inductive Step: Suppose now that n ≥ 0 and that
T (m) ≤ T (m + 1)
for every integer m such that 0 ≤ m ≤ n. It is necessary and sufficient to prove, using only these
assumptions, that
T (n + 1) ≤ T (n + 2)
2 c) + 1
T (n + 1) = T (b n+1
and
2 c) + 1.
T (n + 2) = T (b n+2
2 c) + 1 = T (b 2 c) + 1 = T (n + 2),
T (n + 1) = T (b n+1 n+2
2 c = b 2 c + 1,
b n+2 n+1
2 c ≤ n.
0 ≤ b n+1
It therefore follows by the above inequalities, and the inductive hypothesis, that
2 c) ≤ T (b 2 c)
T (b n+1 n+2
T (n + 1) ≤ T (n + 2)
can be obtained from the previous one by adding one to both sides.
It now follows by induction on n that T (n) ≤ T (n + 1) for every integer n ≥ 0, as desired.
119
2: Proof That T (n) ≥ T (2k ) for k = blog2 nc
This should be fairly obvious, since n and 2blog2 nc are both integers and since
2blog2 nc ≤ n.
It would be acceptable if you simply wrote this conclusion down, after completing the above
proof that T is a nondecreasing function.
However, if you really wanted to, you could prove this last inequality using induction on the
difference between n and 2blog2 nc .
120
8.5.2 Application to an Example
Consider, again, the recurrence that was used in the second example for the previous method,
if n ≤ 1,
0
T (n) = 1 if n = 2,
T (b n c) + 1 if n ≥ 3.
2
Before we begin, there is something that should be noted that will be useful here and for later
problems:
Lemma 8.2. If h is an integer that is greater than or equal to two and n and i are nonnegative
integers, then
$ % ¹ º
b hni c n
= i+1 .
h h
Proof. This is easily proved once you observe that every nonnegative integer n has a “base h”
representation,
X̀
n= aj hj
j=0
Now, back to the above example. If n is sufficiently large then we can repeatedly apply the
recursive definition (that is, apply it “iteratively”) and observe that
T (n) = T (b n2 c) + 1 by the recursive definition of T (n)
= (T (b n4 c) + 1) + 1 by the recursive definition again, and the lemma
X
2
= T (b 2n2 c) + 1
i=1
X
2
= (T (b 2n3 c) + 1) + 1 by the recursive definition and the lemma, again
i=1
X
3
= T (b 2n3 c) + 1
i=1
X
3
= (T (b 2n4 c) + 1) + by the recursive definition and the lemma, again
i=1
X
4
= T (b 2n4 c) + ...
i=1
121
The above derivation is correct as long as b 2n3 c ≥ 3, that is, provided that n ≥ 24 = 3 · 23 .
(Why?)
Based on this, you might guess the following.
Conjecture. If l ≥ 0 and n ≥ 3 · 2l−1 then
X
l
T (n) = T (b 2nl c) + 1. (8.5)
i=1
It turns out that this conjecture is correct — and you can prove it (fairly easily) as follows.
as required.
Inductive Step: Suppose now that l ≥ 0, and that if n ≥ 3 · 2l−1 then
X
l
T (n) = T (b 2nl c + 1.
i=1
It is necessary and sufficient to prove, using only this assumption, that if n ≥ 3 · 2l then
X
l+1
T (n) = T (b 2l+1 c) + n
1.
i=1
122
Now, if n ≥ 3, we can set
l = blog2 nc − 1;
l ≥ 0 since n ≥ 3, and
so that we can immediately conclude — using the result that was established by induction on l —
that
X
l
T (n) = T (b 2nl c) + 1
i=1
blog2 nc−1
X
= T (b 2blog2nnc−1 c) + 1.
i=1
Now,
n
< 2blog2 nc ≤ n,
2
so
n n
< 2blog2 nc−1 ≤ ,
4 2
and therefore (since n > 0),
2≤ n
2blog2 nc−1
< 4.
It follows that
2 ≤ b 2blog2nnc−1 c ≤ 3,
so that
T (b 2blog2nnc−1 c)
T (2) = T (3) = 1,
123
Now we’re left with the problem of finding a closed form for a summation. In the case of this
example, it’s a trivial one, and it should be clear now that
blog2 nc−1
X
T (n) = 1 + 1 = 1 + (blog2 nc − 1) = blog2 nc.
i=1
Of course, since the sum was so easy to solve, you could have solved it immediately — writing
l instead of
X
l
1
i=1
wherever the former expression appears in the above derivation. The sum has been left in, in this
example, to make it look more like what you’d have when the problem is harder.
A comparison with the derivation given in the previous subsection should confirm that we’ve
now obtained a more precise result than we had before — we’d only showed that
T (n) ∈ Θ(log2 n)
using the substitution method. However, we had to perform some additional algebraic manipula-
tions, and see and confirm a pattern (as given by the above “conjecture”), in apply the iteration
method.
You don’t often get a “pattern” that’s quite as simple as the above. It’s slightly more common
to get a pattern that looks more like
X
l
T (n) = al T (b bnl c) + f (i),
i=1
where al and bl are frequently positive integers that depend on l (but not on n) and where f (i) is
some function of i. Other “patterns” are possible as well.
• the appearance of extra additive terms appearing in the right hand side of the definitions.
The “techniques” in this section are actually methods that allow us to simplify recurrences,
reducing the problems associated with ceiling and floor functions and additional additive terms.
We’ll generally apply these techniques to convert a given recurrence into one that is easier to solve,
in such a way that the solution for the simpler recurrence can be used to recover a solution or
bound for the one we started with.
124
8.6.1 Restricting the Domain
The second example for the “substitution method,” particularly the part in which we tried to prove
that
T (n) ∈ Ω(log2 n),
also illustrates the use of the simplification method. This method seems useful when floors and
ceilings are involved — especially when T (n) is defined in terms of either T (b nh c) or T (d nh e), where
h is some positive integer that is greater than or equal to two.
The “method” can be described as follows.
1. Prove (generally using induction on n) that the function T is nondecreasing, that is, T (n) ≤
T (n + 1) for every integer n ≥ 0, using the given recurrence for T .
2. Identify an infinite set of integers n such that T (n) = T̂ (n), where T̂ is a function defined on
the reals, by taking the given recurrence for T and eliminating all applications of the floor or
ceiling function — and, furthermore, where T̂ (n) is only recursively defined in terms of T̂ (m)
where 0 ≤ m < n and m is an integer.
In the special case given above, that T (n) is only defined in terms of the value of the function
at the floor or ceiling of nh , you can generally choose this set of integers to include all the
integer powers of h.
3. Now, try to apply the substitution or iteration method to T (n) (or T̂ (n)) for integers n that
belong to the set you chose in the previous step. You’ll frequently find that this is easier than
it would be to apply the substitution method to T (n) directly in the general case, because
the floor and ceiling functions don’t cause as many problems.
4. Let’s suppose that you’ve managed to prove that
ĉg(n) ≤ T (n) ≤ cg(n)
for positive constants ĉ and c, some useful function g, in the special case that n belongs to the
infinite set chosen above. Now, take advantage of the fact that T is a nondecreasing function
(as proved in step 1) to conclude that
ĉg(nL ) ≤ T (nL ) ≤ T (n) ≤ T (nU ) ≤ cg(nU )
where nL and nU are members of the infinite set you chose in step 2, such that
nL ≤ n ≤ nU .
In the case that your infinite set consisted of all the integer powers of h, as above, you’d
generally choose
nL = hblogh nc and nU = hdlogh ne
so that
n
nL > and nU < h · n.
h
If the function g grows sufficiently slowly (say, it’s only logarithmic or polynomial, rather
than exponential in n), then g(nU ) won’t be too much larger than g(nL ), and this may be
good enough to allow you to prove that
T (n) ∈ Θ(g(n)).
As noted above, this method was applied in the derivation at the end of Section 8.4.3.
125
8.6.2 Change of Variable
You can sometimes make progress by rewriting a recursive definition, so that the function is defined
in terms of a different variable (namely, some function of the variable that the first recurrence
mentioned).
Consider, again, the recurrence used in the second example for “the substitution method,”
if n ≤ 1,
0
T (n) = 1 if n = 2, (8.6)
T (b n c) + 1 if n ≥ 3.
2
It was argued (in essence) in that section that it would be sufficient to consider the special case
that n is a power of two, that is, that
n = 2k (8.7)
T̂ (k) = T (n)
= T (2k )
if 2k ≤ 1,
0
= 1 if 2k = 2,
T (b 2k c) + 1 if 2k ≥ 3,
2
if k ≤ 0,
0
= 1 if k = 1,
T (2k−1 ) + 1 if k ≥ 2,
if k ≤ 0,
0
= 1 if k = 1,
T̂ (k − 1) + 1 if k ≥ 2.
In the second-to-last line, we took advantage of the fact that k was required to be an integer
to conclude that k must be greater than or equal to two in order for 2k to be greater than or equal
to three.
Rewriting this more succinctly, we have
0 if k ≤ 0,
T̂ (k) = 1 if k = 1,
T̂ (k − 1) + 1 if k ≥ 2.
and it should be very easy to see (and prove by induction on k) that this recurrence has the solution
126
Now (if we wish to) we can deal with the general case, by proving as before that T (n) is a
nondecreasing function of n, so that
The additional additive term “+3” in the final case makes this difficult to handle using the tech-
niques that have been introduced so far. (Give it a try, if you don’t see why this is the case.)
Suppose, instead, that we consider the function
U (n) = T (n) + 3.
Then
U (n) = T (n) + 3 = 5 if n ≤ 0,
and
U (1) = T (1) + 3 = 6.
U (n) = T (n) + 3
= (T (n − 1) + T (n − 2) + 3) + 3
= (T (n − 1) + 3) + (T (n − 2) + 3)
= U (n − 1) + U (n − 2).
That is,
if n ≤ 0,
5
U (n) = 6 if n = 1,
U (n − 1) + U (n − 2) if n ≥ 2.
127
Now, since the Fibonacci numbers satisfy the recurrence
0 if n = 0,
Fn = 1 if n = 1,
F + Fn−2 if n ≥ 2,
n−1
you should find that it is very easy to use the substitution method to prove that
U (n) ∈ Θ(Fn+1 ).
as well.
m = 2k − 1
for an integer k ≥ 0.
Use the “change of function” approach, given above, to use the recursive definition of T (m) in
order to produce a recursive definition for T̂ (k), where k is an integer, m = 2k −1, and T̂ (k) = T (m).
128
You should find, after you’ve done this, that the iteration method can be used without too
much trouble to find a closed form for the function T̂ .
Then, use the fact (which you proved at the beginning) that T is an increasing function of m, to
recover a tight asymptotic bound, in closed form, for T . That is, use all this to discover a function
g(m) which is in closed form, such that you can conclude from the above that
T (m) ∈ Θ(g(m)).
1. The algorithm uses more than zero steps, but at most c steps, on every input instance whose
size is less than b.
2. It solves instances of size n, for n ≥ b, by forming a smaller instances that are each of size
at most d nb e, solving these smaller instances recursively, and then deriving a solution for the
original instance using the solutions for the derived ones.
3. The number of steps it uses for an input of size n, excluding the cost of the recursive calls, is
at most f (n) in the worst case.
Let T (n) be the number of steps used by this algorithm on an input instance of size n in the
worst case, and suppose T (n) is nondecreasing. Then T (n) satisfies the following recurrence:
(
c if n < b,
T (n) ≤ ¡ n ¢
aT d b e + f (n) if n ≥ b.
Similar algorithms, with slightly different behaviours, might have running times bounded by
recurrences involving T (b nb c) instead of T (d nb e).
With additional effort (proving that the “worst case” really can arise, on a regular basis, when
subproblems are being formed), you can sometimes prove that an algorithm’s running time also
129
satisfies a recurrence like
(
ĉ if n < b,
T (n) ≥ ¡ n ¢
ˆ
aT d b e + f (n) if n ≥ b,
as well, where ĉ is also a positive constant (possibly different from c) and fˆ(n) is also an asymptot-
ically positive function (possibly different from f (n) — but, ideally, in Θ(f (n))). That is, you can
sometimes prove that the solution of a recurrence of this form is also a lower bound for the number
of steps used by an algorithm on inputs of size n in the worst case.
Note, though, that this doesn’t follow immediately from the properties of the algorithm that
are stated before the first recurrence.
The following result can often be used to find closed forms for functions bounding the worst
case running times of these algorithms.
Theorem 8.3 (Master Theorem). Let a, b, and c be constants such that a is greater than or
equal to one, b is strictly greater than one, c is greater than zero, and let f (n) be an asymptotically
positive function of n such that f (n) is defined whenever n ≥ b.
Let T (n) be a function such that 0 < T (n) ≤ c whenever n < b and such that
¡ ¢
T (n) = aT d nb e + f (n) (8.8)
1. If f (n) ∈ O(n(logb a)−² ) for some constant ² > 0 (which does not depend on n), then T (n) ∈
Θ(nlogb a ).
3. If f (n) ∈ Ω(n(logb a)+² ) for some constant ² > 0 (which does not depend on n), and there
exists a constant d such that d < 1 and
¡ ¢
af d nb e ≤ df (n)
Furthermore, the function T (n) is also bounded asymptotically as above if 0 < T (n) ≤ c whenever
n < b and
¡ ¢
T (n) = aT b nb c + f (n)
1. It doesn’t quite apply to recurrences of the form given in the previous subsection, because
those included inequalities, and the recurrence given in the statement of the theorem is an
equality. However, we’ll see that the master theorem is extremely useful in spite of this.
2. As we’ll see later, it also doesn’t specify an asymptotic bound for every recurrence of this
form.
130
8.7.2 Proof of the Master Theorem
There isn’t time to include a proof of the above theorem in lectures, and it isn’t necessary to
understand the proof in order to apply it.
However, a proof is included in Section 4.4 of Cormen, Leiserson, and Rivest’s book [3]. Slightly
different notation is used in their book (and, you should read the material on pages 53–54 of their
book, before looking at Section 4.4). However, the “master theorem” given above is implied by the
version of the theorem that is stated and proved in the text, so that the proof in Cormen, Leiserson,
and Rivest’s book proves the above theorem (as well as the version in their text).
You might be wondering why the other techniques for analyzing recurrences were included in
CPSC 413, if the master theorem exists. One reason is that there are useful recursive programs
whose running times are given by recurrences that can’t be solved using the master theorem.
Another (in case you want to understand a proof of what you’re using) is that the proof of the
master theorem uses these other techniques, as you’ll discover if you look at Cormen, Leiserson,
and Rivest’s book.
If f is is defined as above then f (n) ∈ Ω(2n ); indeed, f (n) ≥ 2n for every integer n ≥ 2.
However, if we define a function T by the recurrence
(
1 if n ≤ 1,
T (n) = ¡ ¢
4T d n2 e + f (n) if n ≥ 2,
then this corresponds to a recurrence with the form described in the master theorem, with a = 4,
b = 2, and f (n) as above. Since logb a = 2, it’s certainly the case that f (n) ∈ Ω(nlogb a+² ) for a
positive constant ². However, the third case of the master theorem is not satisfied, because there
are infinitely many integers n such that dlog2 (log2 n2 )e = dlog2 (log2 n)e, so that
¡ ¢ ¡ ¢
af d nb e = 4f d n2 e = 4f (n) > f (n) infinitely often,
eliminating the possibility that there might exist any constant d < 1 such that
¡ ¢
af d nb e ≤ df (n)
131
for all sufficiently large n. That is, the third case does not hold because this “regularity condition”
is not satisfied.
Worse yet, it isn’t just the case that the conditions described as necessary in the theorem are
not satisfied: The conclusion you’d like to achieve in this case isn’t satisfied either, because
Furthermore, the function T (n) is also bounded asymptotically as above if 0 < T (n) ≤ c when-
ever n < b and
¡ ¢
T (n) = aT b nb c + f (n)
This version of the theorem is more restrictive than the original one, since it includes the new
condition that
Therefore, there may be cases when you must try to use the original version, because this last
condition is not satisfied.
However, this second version is easier to apply, when it can be applied at all — note that
the constant “²” mentioned in the original version (not to mention, the need to prove asymptotic
bounds in order to established each of the three cases), and the “regularity condition” (for the third
case) have been eliminated.
132
8.7.5 Proof of the Simplified Version of the Theorem (Optional)
A proof of this simplified version of the theorem is given in the rest of this section. More precisely,
it’s shown here that Theorem 8.4 is a consequence of Theorem 8.3. This isn’t required reading for
CPSC 413.
However, it might be of interest if you’d like to discover how one can show that “the regularity
condition” is satisfied when you’re trying to apply the original version of the master theorem;
something like this is included in the proof of the third case that’s mentioned in the simplified
version of the theorem.
Recall now that each version of the theorem gives three different asymptotic bounds correspond-
ing to three possible cases. Since each of the conclusions (asymptotic bounds) for the three cases in
the simplified theorem is the same as the conclusion given in the corresponding case in the original
theorem, it is sufficient to show that the each of the conditions that must be satisfied (as stated in
the simplified theorem) implies the corresponding condition in the original version of the theorem.
Thus, the three cases will each be considered separately, and this is how the first two cases will be
handled. As shown below, the final case will require a bit more work.
Suppose, henceforth, that f (n) ∈ Θ(nα (log2 n)β ) for constants α and β.
as well. Therefore f (n) ∈ O(nlogb a−² ), so the first case of the original version of the master theorem
is applicable, as required.
133
The Third Case
Suppose, finally, that the third case of the simplified version of the master theorem is applicable;
then α > logb a.
The Lower Bound is Easy. It is easy to establish by induction on n that T (n) ≥ 0 for every
positive integer n. This, and the original recursive definition of T , imply that
Switching Recurrences. Since f (n) ∈ Θ(nα (log2 n)β ), there exist constants e > 0 and N ≥ 0
such that
Since it’s true that nα (log2 n)β > 0 whenever n ≥ b > 1, this implies that
Confirming the First Condition. Since the third case of the simplified master theorem is
applicable, α > logb a. Therefore, let
²= 1
2 (α − logb a) ;
ˆ
f (n) ênα (log2 n)β n²
≥ = ê · .
n(logb a)+² nα−² (log2 n)−β
n²
lim = +∞,
n→+∞ (log2 n)−β
134
and the above inequality implies that
fˆ(n)
lim = +∞
n→+∞ n(logb a)+²
as well. Therefore
f (n) ∈ Ω(n(logb a)+² ),
as is needed to satisfy the first condition needed to establish that the third case of the master
theorem is applicable.
135
Conclusion, for the Third Case. Since all the required conditions are satisfied, the third case
of the original version of the master theorem applies to the recurrence for U (n). It follows that
so, in particular,
as required. Therefore, T (n) ∈ Θ(f (n)) (as claimed by the third case for the “simplified” version
of the master theorem), as argued above.
for constants α and β. If you manage to do this as well then you can apply Theorem 8.4 to conclude
that
1. T (n) ∈ Θ(nlogb a ) if α < logb a;
2. f (n) ∈ Θ(nlogb a ),
3. f (n) ∈ Ω(n(logb a)+² ) for a positive constant ², and there exists a positive constant d < 1 such
that
¡ ¢
af d nb e ≤ df (n)
136
If this limit exists and is zero, then f (n) ∈ o(nlogb a ), so that only the first case is possible (but,
this case might not apply either). If this limit exists and is +∞ then f (n) ∈ ω(nlogb a ), so that
only the third case is possible (but this might not apply either). Finally, if the limit exists and is
a positive constant then f (n) ∈ Θ(nlogb a ), in which case the second case definitely does hold.
Of course it is possible that the limit doesn’t exist at all; then the first and third cases are
impossible (because the limit tests for little-oh and little-omega were necessary as well as sufficient),
so only the second case is possible. However, it is possible that you’ll be able to prove that
f (n) ∈ Θ(nlogb a ) even though the above limit doesn’t exist — and you’ll then be able to conclude
that the second case holds, immediately after that.
If one of the three cases covered in the master theorem does apply, then the theorem states an
asymptotic bound in closed form for your recurrence, so you can simply write it down. Otherwise,
you must conclude that the master theorem is not applicable and (if necessary) try to find a closed
form by other means.
An Example
Suppose, for example, that you’ve been given an algorithm whose running time satisfies the recur-
rence
(
7 if n ≤ 1,
T (n) ≤ ¡ n ¢
T b 2 c + 5 if n ≥ 2.
Now, the above recurrence isn’t in the form you want, since it includes an inequality. However,
if you define the function
(
7 if n ≤ 1,
U (n) = ¡ ¢
U b n2 c + 5 if n ≥ 2,
then it’s very easy to prove by induction on n that T (n) ≤ U (n) for every integer n ≥ 1, and this
latter recurrence is in the desired form.
In particular, it has the form
(
c if n < b,
U (n) = ¡ ¢
aU b nb c + f (n) if n ≥ b,
where a = 1, b = 2, c = 7, and f (n) = 5.
Furthermore, f (n) = 5 ∈ Θ(nα (log2 n)β ), for α = β = 0, so that the simplified version of the
master theorem (Theorem 8.4) can be applied.
Now, logb a = log2 1 = 0, and therefore nlogb a = n0 = 1. It should be clear, now, that the
middle case mentioned in the simplified master theorem applies:
α = logb a and β = 0,
so we can conclude, by this theorem, that
U (n) ∈ Θ(nlogb a log2 n) = Θ(log2 n).
Since T (n) ≤ U (n), we can also conclude that
T (n) ∈ O(log2 n).
We can’t conclude that T (n) ∈ Θ(log2 n), because the original recurrence for T (n) (which
included an inequality, rather than an equation) is satisfied by functions that grow more slowly
than logarithmically in n — including, for example, the constant function T (n) = 1.
137
Another Example
Suppose, instead, that T had been defined by the recurrence
(
7 if n ≤ 1,
T (n) ≥ ¡ ¢ √
T b n2 c + 5d n e if n ≥ 2.
in this case, it’s easy to see that T (n) ≥ L(n) for every integer n ≥ 1 (and to prove it by induction
on n).
Once again, the recurrence for L(n) has the desired form, and it corresponds to the choice of
√
constants a = 1, b = 2, c = 7, and f (n) = 5d n e.
Now, f (n) ∈ Θ(nα (log2 n)β ) for α = 12 and β = 0 so that, once again, the simplified version of
the master theorem can be applied.
As before, logb a = 0, so that nlogb a = 1. Now, the third case covered in Theorem 8.4 applies:
α > logb a.
√
Therefore, we can conclude that L(n) ∈ Θ(f (n)) = Θ( n ).
Suppose (in order to obtain an example in which the original version of the theorem is to be
used) that you had failed to notice that f (n) was in the form needed for the simplified version of
the theorem to be applicable. You’d therefore try to apply the original version of the theorem,
Theorem 8.3, instead.
In this case, since logb a = 0 once again, you can eliminate the first two cases, by noting that
f (n) 6∈ O(nlogb a ); only the third case is possible.
Now, the first part of the condition required for the third case is satisfied, since
√
f (n) = 5d n e ∈ Ω(nlogb a+² ) = Ω(n² ), for ² = 0.25.
Indeed, we could have chosen ² to be any positive constant that is strictly greater than zero, and
less than or equal to one-half, and the above statement would hold.
We must also establish “the regularity condition.” Fortunately, this isn’t too difficult, for this
example: Since a = 1 and b = 2,
¡ ¢ ¡ ¢
af d nb e = f d n2 e
»q ¼
=5 d(n/2)e
»q ¼
≤5 (n + 1)/2
q
≤ 5 (n + 1)/2 + 5
√
≤4 n if n is sufficiently large (in particular, if n ≥ 127)
√
≤ 5 · 5d ne
4
= 45 f (n).
138
That is, you can satisfy the regularity condition by choosing d = 45 .
Now we can conclude from the original version of the master theorem (as well as from the
simplified version, as argued above) that
√
L(n) ∈ Θ(f (n)) = Θ( n ),
and, since T (n) ≥ L(n) for every integer n ≥ 1, we can also conclude that
√
T (n) ∈ Ω( n ).
√
Once again, we can’t conclude that T (n) ∈ O( n) because the original recurrence contains an
√
inequality instead of an equality and is satisfied by functions that aren’t in O( n). For example,
the function T (n) = 1000n satisfies the original recurrence.
A Third Example
As a final example, suppose that
(
1 if n ≤ 1,
T (n) = ¡ ¢
2T b n2 c + n log2 n if n ≥ 2.
In this case, the recurrence has the desired form — it corresponds to the choices a = b = 2, c = 1,
and f (n) = n log2 n.
The simplified version of the theorem, Theorem 8.4 is applicable — or, at least, it initially seems
to be, since f (n) ∈ Θ(nα (log2 n)β ), for α = β = 1.
However, logb a = 1 as well. Now, since α = logb a, neither the first nor third cases are
applicable. Unfortunately the second case is not applicable either, because β 6= 0.
If we try to use the original version of the master theorem (Theorem 8.3), instead, then we
encounter a similar difficulty: Since logb a = log2 2 = 1,
• f (n) = n log2 n ∈ ω(n(logb a)−² ) = ω(n1−² ), for every positive constant ², and therefore f (n)
is not in O(n(logb a)−² ), for any positive constant ². Therefore the first case mentioned in the
master theorem does not apply (you can also use the limit test to eliminate this case).
• f (n) = n log2 n ∈ ω(nlogb a ) = ω(n), so f (n) 6∈ Θ(nlogb a ), and the second case mentioned in
the master theorem does not apply (you could use the limit test to eliminate this case, as
well); and
• f (n) = n log2 n ∈ o(n(logb a)+² ) = o(n1+² ), for every positive constant ², so f (n) is not in
Ω(n(logb a)+² ) for any positive constant ² (even though f (n) ∈ Ω(nlogb a )). Therefore the third
case mentioned in the master theorem does not apply, either.
So, this is an example such that the master theorem is not applicable at all, and so that it can’t
be used to find a tight asymptotic bound for the function defined by the recurrence.
Furthermore, it should be noted as well, that in general, there is no point in considering the
original version of the master theorem, when you have been unable to apply the simplified version
because f (n) ∈ Θ(nα (log2 n)β ) for constants α and β such that α = logb a but β 6= 0: You’ll
always discover, under these circumstances, that the original version of the master theorem isn’t
applicable, either.
Exercise: Use one or more of the techniques for solving recurrences, introduced in CPSC 413 before
this, to prove that T (n) ∈ Θ(n(log2 n)2 ) if T (n) is as defined above.
139
8.8 Solving Linear Recurrences with Constant Coefficients
This section concerns another special form of recurrence that has applications in algorithm analysis
and a way to solve a recurrence of this form; it might not be covered in CPSC 413 if there isn’t
time for it.
On the other hand, the recurrences that can be solved using “the master theorem,” are examples
of recurrences that are not “linear recurrences with constant coefficients.”
8.8.2 Closed Forms for Solutions of Linear Recurrences with Constant Coeffi-
cients
Definition 8.8. The characteristic polynomial of the recurrence given in equation (8.10) is the
polynomial
140
As you may have seen in an algebra course, every polynomial with complex numbers as coeffi-
cients can be factored into a product of linear polynomials with complex coefficients. In particular,
if
as above, then there exists some positive integer s ≤ t, distinct complex numbers β1 , β2 , . . . , βs ,
and positive integers ν1 , ν2 , . . . , νs such that
ν1 + ν2 + · · · + νs = t
and
Y
s
f (x) = (x − βi )νi . (8.12)
i=1
In this case, we call βi a root of f (x) and say that νi is the multiplicity of this root.
Note that, since t is chosen so that at 6= 0, 0 is not a root of the characteristic polynomial of a
linear recurrence with constant coefficients.
The following theorem gives a way to find closed forms for functions expressed by linear recur-
rences with constant coefficients. It won’t be proved in CPSC 413, but a more general method that
could be used to prove it will be mentioned in the next section.
Theorem 8.9. Suppose the characteristic polynomial (given by equation (8.11)) of the linear re-
currence in equation (8.10) has the factorization shown in equation (8.12), above.
Then there exist polynomials q1 (x), q2 (x), . . . , qs (x) such that qi (x) has degree less than νi for
1 ≤ i ≤ s and such that
1. Compute and factor the characteristic polynomial of the linear recurrence, in order to discover
the roots of this polynomial and their multiplicities;
2. Use the initial values (T (0), T (1), . . . , T (t−1)) in order to solve for the “unknown” polynomials
that are multiplied by powers of the roots in the closed form given in equation (8.13).
It will turn out that the number of unknown coefficients that one needs to discover, in order to
perform the second step, will always be equal to the number of initial values given for the recurrence
(that is, t). Furthermore, one will always be able to find these coefficients by solving a nonsingular
141
system of t linear equations in t unknowns, so that the second step can always be performed by
setting up a system of linear equations and then using Gaussian Elimination to solve it.
Consider, for example, the “Fibonacci” recurrence, given in Example 8.6. Since t = 2 and
a1 = a2 = 1, this recurrence has characteristic polynomial
f (x) = x2 − x − 1.
This polynomial can be factored using the binomial theorem, to show that
à √ !à √ !
1+ 5 1− 5
f (x) = x − x − 1 = x −
2
x− .
2 2
√ √
Thus the polynomial has two roots, β1 = (1 + 5)/2 and β2 = (1 − 5)/2, and each root has
multiplicity one. It follows by Theorem 8.9 that the recurrence has a closed form
Fn = p1 (n)β1n + p2 (n)β2n ,
where each unknown polynomial p1 (n) and p2 (n) has degree at most 1 − 1 = 0. Thus, the polyno-
mials are both unknown “constants,” and
Fn = c1 β1n + c2 β2n ,
where c1 and c2 are complex numbers whose values are yet to be determined.
At this point, we can make use of the initial values F0 = 0 and F1 = 1 to obtain two equations
in the “unknowns” c1 and c2 :
0 = F0 = c1 β10 + c2 β20 = c1 + c2 ,
à √ ! à √ !
1 + 5 1 − 5
1 = F1 = c1 β11 + c2 β21 = c1 + c2 .
2 2
That is,
" #" # " #
1√ 1√ c1 0
1+ 5 1− 5 = .
2 2
c2 1
Next, consider the recurrence given in example 8.7. In this case t = 3, a1 = 7, a2 = −16, and
a3 = 12, so the characteristic polynomial of the recurrence is
which has one root β1 = 2 with multiplicity two, and another root β2 = 3 with multiplicity one. In
this case, a solution for the recurrence has a closed form
142
where the unknown polynomial p1 (n) has degree at most 2 − 1 = 1 and the unknown polynomial
p2 (n) has degree at most 1 − 1 = 0, so that
c1 · 0 · 20 + c2 · 20 + c3 · 30 = 1,
c1 · 1 · 21 + c2 · 21 + c3 · 31 = 1,
c1 · 2 · 22 + c2 · 22 + c3 · 32 = 2;
that is,
0 1 1 c1 1
2 2 3 c2 = 1 .
8 4 9 c3 2
T (n) = − 32 · n · 2n − 2n + 2 · 3n for n ≥ 0.
Exercise (Yet more practice in the use of mathematical induction): Prove that the closed forms
obtained in the last two examples are correct.
143
8.10 Exercises
1. Try to use “the iteration method” to express each of the following summations as recurrences.
You may assume that n is a power of two for the first three parts, and you may assume that
k
n is a power of a power of two (so that n = 2(2 ) for some integer k) for the last two parts of
this question.
2. Now prove that each of the functions T (n) defined by recurrences in the first question is a
nondecreasing function (defined on the set of positive integers).
Use this, and your answer for Question #1, to find a function g(n) in closed form, and
constants cL and cU , such that
for each part of Question #1. Try to make your estimates as tight as you can (just to see
how well you can do).
3. For each of the functions T (n) defined in the first three parts of Question #1, give recurrences
for the corresponding functions
4. Now try to use the “substitution method” to answer the following question. I recommend
that you attempt Question #1 before you read this one.
(a) Show that if T (n) is as defined in Question #1(a) then T (n) ∈ Θ(n2 ). If time permits
then you should try to do this three ways (to see what happens in each case):
i. Try to show that T (n) ≤ cn2 and T (n) ≥ ĉn2 for unknown positive constants c
and ĉ. (Note though, that this attempt might not be successful!)
ii. Consider the function U (n) = T (n) + n2 and try to show that U (n) ≤ cn2 and
U (n) ≥ ĉn2 for unknown positive constants c and ĉ instead.
iii. Try to show that T (n) ≤ cn2 − dn and T (n) ≥ ĉn2 for unknown positive constants
c and ĉ and an unknown constant d.
(b) Show that if T (n) is as defined in Question #1(b) then T (n) ∈ Θ(n2 log2 n).
(c) Show that if T (n) is as defined in Question #1(c) then T (n) ∈ Θ(n3 ).
(d) Show that if T (n) is as defined in Question #1(d) then T (n) ∈ Θ(log2 n).
(e) Show that if T (n) is as defined in Question #1(e) then T (n) ∈ Θ(n log2 log2 n).
144
5. Now try to use the master theorem (Theorems 8.3 and 8.4) to solve the recurrences given in
Question #1. This should be reasonably straightforward for the first three parts, but you
will probably need to “simplify the recurrence” for the last two parts in order to apply the
master theorem successfully.
6. Try to use the master theorem (Theorems 8.3 and 8.4) to solve the following additional
recurrences.
7. Find closed forms for the functions given by the following linear recurrences with constant
coefficients.
T (n) = 4T (n − 1) − 6T (n − 2) + 4T (n − 3) − T (n − 4) if n ≥ 4.
Note that 1 is a root of the characteristic polynomial of this linear recurrence, with
multiplicity greater than one.
Hints for selected exercises are given in the next section; solutions for Exercises #1(c), 2(c),
3(c), 4(c), 5(b), 6(b), 6(c), and 7(c) can be found in Section 11.3.1.
X
h−1
T (n) = 4h T (n/2h ) + n 2i .
i=0
Exercise #1(b): Try to establish the following pattern, which should become evident after you
apply the iteration method to the given recurrence: If h ≥ 0 and n is a power of two such that
n ≤ 2h , then
145
Exercise #1(c): Try to establish the following pattern, which should become evident after you
apply the iteration method to the given recurrence: If h ≥ 0 and n is a power of two such that
n ≤ 2h , then
X³
h−1 ´i
T (n) = 4h T (n/2h ) + n3 1
2 .
i=0
Exercise #1(d): Try to establish the following pattern, which should become evident after you
apply the iteration method to the given recurrence: If h ≥ 0 and n is a power of a power of two
h
such that n ≤ 2(2 ) , then
³ h
´ X³
h−1 ´i
T (n) = T n1/2 + log2 n 1
2 .
i=0
Exercise #1(e): Try to establish the following pattern, which should become evident after you
apply the iteration method to the given recurrence: If h ≥ 0 and n is a power of a power of two
h
such that n ≤ 2(2 ) , then
³ h
´
T (n) = n
h T n1/2 + hn.
n1/2
Exercise #7: You’ll need to start by computing and factoring the characteristic polynomial of
the linear recurrence in each case. The information given in the last few parts implies that the
characteristic polynomial is divisible by x − 1 (or even (x − 1)2 ), and this should help you to
completely factor the polynomial.
146
8.12 Sample Tests
This is a long chapter, which leads into the first “algorithm design” topic, and two tests containing
recurrence questions were used in both fall 1996 and fall 1997. However, the second of the tests used
in fall 1997 was only used as a “practice test,” as a warmup for the midterm and final examination,
and it didn’t count for credit.
Solutions for the following tests can be found in Section 11.3.2.
for n ≥ 2. Use the “substitution method” to prove that T (n) ∈ O(n(log2 n)2 ) whenever
n = 2k is a power of two.
2. (10 marks) Now use the “iteration method” to find an expression in closed form that is an
exact solution for the recurrence given in Question #1. Once again, you may assume that
n = 2k is a power of two.
X
k ³ ´ X
k X
k
log2 n
2i
= log2 (2j ) = j.
i=0 j=0 j=0
Note: A small number of bonus marks will be awarded if you also use mathematical induction
to prove that your solution is correct.
147
8.12.2 Second Class Test for 1996
Instructions:
Attempt all questions. Write answers on the question sheets.
No aids allowed.
Duration: 50 minutes
(a) (4 marks) Write down a recurrence for the number of steps used by the above multipli-
cation algorithm (as a function of n) in the worst case.
(b) (3 marks) Find a function f (n) in closed form such that this algorithm uses Θ(f (n)) steps
to multiply two n-digit integers together.
2. (5 marks) Write a recursive function that takes a pointer to the root of a binary tree as input,
and returns the sum of the values stored at the nodes of the tree.
Use the following notation: if p is a pointer to a node, then
• ∗p.left is a pointer to the left child (and is “null” if the node does not have a left child);
• ∗p.right is a pointer to the right child (and is “null” if the node does not have a right
child);
• ∗p.value is the value stored at the node.
3. Consider two “integer division” algorithms (that compute the quotient and remainder ob-
tained by dividing one n-digit input integer by a second n-digit input integer):
• Algorithm A uses T (n) steps, when given n-digit integers as input, where
(
c1 if n < 4,
T (n) =
7T (d n4 e) + c2 n + c3 if n ≥ 4,
(a) (6 marks) Find a function f (n) in closed form such that T (n) ∈ Θ(f (n)) (where T (n) is
the number of steps used by Algorithm A, as above).
148
(b) (2 marks) Say which of the above two algorithms is asymptotically faster — that is, say
which algorithm uses a smaller number of steps, when given n-digit integers as inputs,
for all sufficiently large n.
The following approximations may be helpful as you try to answer these questions. Each is a
slight under-approximation, but no approximation is “off” by 0.01 or more. Thus, for example,
you should interpret the claim below that log2 3 ∼
= 1.58 to mean that 1.58 ≤ log2 3 < 1.59.
log2 2 = 1 log3 2 ∼
= 0.63 log4 2 = 0.5 log5 2 ∼
= 0.43 log6 2 ∼
= 0.38 log7 2 ∼
= 0.35
log2 3 ∼
= 1.58 log3 3 = 1 log4 3 ∼
= 0.79 log5 3 ∼
= 0.68 log6 3 ∼
= 0.61 log7 3 ∼
= 0.56
log2 4 = 2 log3 4 ∼
= 1.26 log4 4 = 1 log5 4 ∼
= 0.86 log6 4 ∼
= 0.77 log7 4 ∼
= 0.71
log2 5 ∼
= 2.32 log3 5 ∼
= 1.46 log4 5 ∼
= 1.16 log5 5 = 1 log6 5 ∼
= 0.89 log7 5 ∼
= 0.82
log2 6 ∼
= 2.58 log3 6 ∼
= 1.63 log4 6 ∼
= 1.29 log5 6 ∼
= 1.11 log6 6 = 1 log7 6 ∼
= 0.92
log2 7 ∼
= 2.80 log3 7 ∼
= 1.77 log4 7 ∼
= 1.40 log5 7 ∼
= 1.20 log6 7 ∼
= 1.08 log7 7 = 1
log2 8 = 3 log3 8 ∼
= 1.89 log4 8 = 1.5 log5 8 ∼
= 1.29 log6 8 ∼
= 1.16 log7 8 ∼
= 1.06
149
8.12.3 First Class Test for 1997
Instructions:
Attempt all questions. Write answers on the question sheets.
No aids allowed.
Duration: 50 minutes
(a) (8 marks) Use the substitution method — not the master theorem — to prove that
T (n) ∈ O(n4 )
assuming that n is a power of three (so that n = 3h for some integer h ≥ 0).
3. Consider, once again, the recurrence used in Question #2 and the function T (n) that it
defines.
(a) (5 marks) If you used the “iteration method” then you might make the following con-
jecture.
Claim: If k ≥ 0 and n is any power of three such that n ≥ 3k , then
³ ´ X³
k−1 ´i
T (n) = 9k T n
3k
+ n4 1
9 .
i=0
150
(b) (3 marks) Now, use the claim to find an exact closed form for T (n) when n is a power
of three.
4. (4 marks) Perform a “change of variable” to write a recurrence for the function U (h) = T (n),
where h = log3 n (and n is a power of three, so that h is an integer), and T is as defined in
Question #2. For your convenience, here is the recurrence for T once again:
(
0 if n = 1,
T (n) = ¡ ¢
9T b n3 c + n4 if n > 1,
151
8.12.4 Second Class Test for 1997
Instructions:
Attempt all questions. Write answers in the spaces provided below.
Total Marks Available: 25
No Aids Allowed
Duration: 50 minutes
Note: This will not be marked or count toward your CPSC 413 grade.
You’ll need to use the following definitions when answering questions on this test.
A binary heap, of size n, is a binary tree with n nodes that is as complete as possible. The tree
is filled on all levels except possibly the lowest, which is filled from the left to a point. This means
that every binary heap of size n has the same shape as any other binary heap of size n.
However, a binary heap is (usually) not a binary search tree, because it isn’t true that the value
stored at a node in a heap is always greater than or equal to the value stored at the node’s left
child and less than or equal to the value stored at the node’s right child.
Instead, a heap order property is always satisfied: The value stored at a node is always greater
than or equal to all of the values stored at the children of that node. Therefore, the largest value
stored in the heap is always located at the root.
An almost heap of size n is a binary tree with n nodes that has the same shape as a heap of
size n. An “almost heap” might not be a heap, because the heap order property might not be
satisfied — but you’ll be able to turn an “almost heap” into a heap by rearranging the values that
are stored in the “almost heap’s” nodes.
Now, here are some facts that you may use without proving them. Note that it is not necessary
to see the procedure setRoot (which these refer to) in order to use them.
• If the left and right subtrees of the root of an “almost heap” are heaps (and not just “almost
heaps”) and you call the recursive function setRoot, with a pointer to the root of this “almost
heap” as input, then the “almost heap” will be turned into a heap when this procedure
terminates.
• If n ≤ 3 then the left and right subtrees of any “almost heap” of size n are heaps (and not
just “almost heaps”).
1. (10 marks) Write pseudocode for a recursive procedure buildHeap which takes a pointer to
an “almost heap” as input and turns this “almost heap” into a heap.
Your procedure should work from “the bottom up” in the sense that it should recursively
turn the left and right subtrees of the root into heaps before it does anything else (unless, of
course, the input heap has size zero).
Your procedure can, and should, use the procedure setRoot as a subroutine.
If p is a pointer to a node, please use p.left and p.right to refer to pointers to the left and
right children of that node, respectively.
152
Note: If you think about, and you’ve read the instructions, this is easy, and your pseudocode
should fit, comfortably, into the following space — with room to spare!
2. (5 marks) Write a recurrence for the running time T (n) used by your procedure when it is
given a pointer to an “almost heap” of size n as input. You should use the unit cost criterion
and you should assume that n = 2k − 1 for an integer k (that is, your recurrence only needs
to be correct for integers n with this form).
The following additional facts will be useful (and “almost true,”) and you may use them
without proving them:
• If k > 1 and n = 2k − 1 then the left and right subtrees of the root (of an “almost heap”
of size n) are both “almost heaps” with size 2k−1 − 1 = b n2 c.
• When you call setRoot with a pointer to an “almost heap” of size m as input for m ≥ 1,
it uses exactly c1 dlog2 me + c0 steps before it terminates, for some positive constants c1
and c0 (and, it uses c0 steps if m = 0).
3. (5 marks) Use the master theorem to prove that T (n) ∈ Θ(n) if T (n) satisfies the recurrence
you gave to answer the previous question.
4. (5 marks) Finally, use the result you were supposed to prove in the previous question (whether
you managed to prove it or not!), and the assumption that the running time used by your
procedure is a nondecreasing function of n, to prove that this running time is linear in n in
general, and not just in the special case that n = 2k − 1 for some integer k.
153
154
Chapter 9
The midterm tests for fall 1996 and fall 1997 examined the “algorithm analysis” material included
in CPSC 413 and are given below.
Solutions for these tests can be found in Section 11.4.
1. (5 marks — 1 mark for each part) Say whether each of the following claims about functions
of n is true or false. You do not need to prove your answers.
³ ´n
(i) 3
2 ∈ Θ(2n ) Answer:
(iii) 1
1000 n
1/10 ∈ O((log2 n)100 ) Answer:
(iv) 1
1000 n
1/10 ∈ O(n100 ) Answer:
√
(v) n2 + 2n ∈ Θ(2n2 + n) Answer:
2. (10 marks) Let f (n) = en and let g(n) = n for n ≥ 0. Prove that f (n) ∈ ω(g(n)).
155
X
n X
n
3. (10 marks) Let Sn = 13i5.5 = 13i11/2 .
i=1 i=1
Find a function f (n) in closed form such that |f (n) − Sn | ∈ O(n6 ), and prove that this
inequality holds for your choice of the function f .
Generous part marks will be given if you only find a function f (n) in closed form such
that Sn ∈ Θ(f (n)) (and prove that this relationship holds), instead.
(a) If g(x) = 13x5.5 , then g(x) is an increasing function of x (over the positive real numbers).
(b) If r > 1 then ((n + 1)r − nr ) ∈ O(nr−1 ).
4. (5 marks) Find a function f (n) in closed form such that T (n) ∈ Θ(f (n)), where
(
1 if n = 1,
T (n) =
16T (dn/2e) + n3 if n ≥ 2,
5. (10 marks) Find a closed form for the function T (n), where
0 if n = 0,
T (n) = 1 if n = 1,
2T (n − 1) − T (n − 2) if n ≥ 2,
and prove that your answer is correct. You may prove that your answer is correct either by
applying one of the theorems stated in class or by using mathematical induction.
156
9.2 Midterm Test for 1997
Instructions:
Attempt all questions. Write answers on the question sheets in the space provided.
No aids allowed.
Duration: 80 minutes
1. (5 marks — 1 mark for each part) Say whether each of the following claims about functions
of n is true or false. You do not need to prove your answers.
(ii) 1
1000 (log n)
10 ∈ O(n1/100 ) Answer:
√
(iv) n3 + 2n2 ∈ Θ(2n3 + n) Answer:
2. (8 marks) Let f (n) = 3n2 + ln n and let g(n) = n2 for n ≥ 1. Prove that f (n) ∈ Θ(g(n)).
X
n
3. Suppose n ≥ 1, Sn = g(i), where the function g(x) = x
ln(2x) is a nondecreasing function
i=1
of x — you may use this fact without proving it in this question.
(a) (9 marks) Find a function f (n) in closed form such that Sn ∈ Θ(f (n)), and prove that
this holds without using approximation by integrals.
(b) (3 marks) Now suppose G(n) is a function of n such that G0 (n) = g(n). Use approxima-
tion by integrals to give a lower bound for Sn (that is, a function that is always less
than or equal to Sn ). Your answer should be an expression that involves G(n).
4. (5 marks) Find a function f (n) in closed form such that T (n) ∈ Θ(f (n)), where
(
1 if n < 4,
T (n) =
16T (dn/4e) + 2n2 if n ≥ 4,
157
5. (10 marks) Prove that T (n) ∈ O(4n ), where
1 if n = 0,
T (n) = 8 if n = 1,
T (n − 1) + 12T (n − 2) if n ≥ 2.
Hint: You should consider both the cases n = 0 and n = 1 as special cases.
158
Part IV
159
Chapter 10
Proof that n3 − n is Always Even It is possible to prove that n3 − n is divisible by 2 (that is,
that this number is even) for every integer n ≥ 0 by observing that either n is even or n is odd,
and performing a simple case analysis.
In the case that n is even, so is n3 . It follows that n3 − n is even as well, because the difference
between two even numbers is always an even number.
In the case that n is odd, so is n3 . It follows that n3 − n is even, because the difference between
two odd numbers is always even, as well.
Thus n3 − n is even in both cases, so it is even for all n ≥ 0 (in fact for every integer n), as
desired.
Proof that n3 − n is Always Divisible by Three The fact that n3 − n is divisible by 3 for all
n ≥ 0 will be proved by induction on n.
Basis (n = 0):
It is necessary to prove that 03 − 0 is divisible by 3. This is clear, since 03 − 0 = 0 = 3 · 0.
Inductive Step:
Now let n be an arbitrarily chosen integer, and suppose (for now) that n3 − n is divisible by 3.
It is necessary to prove under these assumptions that (n + 1)3 − (n + 1) is divisible by 3 as well.
Since n3 − n is divisible by 3, (n + 1)3 − (n − 1) is divisible by 3 if and only if the difference
between these quantities,
161
is divisible by 3.
Now,
Conclusion of Proof Since n3 − n is divisible by both 2 and 3 for all n ≥ 0, and 6 is the lowest
common multiple of 2 and 3, it follows that n3 − n is divisible by 6 for all n ≥ 0, as well.
A Second Solution
This second proof avoids the use of the “fact from number theory” introduced at the beginning of
the first, and is a proof of the claim directly by induction, instead.
Basis (n = 0):
It is necessary to prove that 03 − 0 is divisible by 6. This is clear, since 03 − 0 = 0 = 6 · 0.
Inductive Step:
Let n be an arbitrarily chosen integer that is greater than or equal to 0, and suppose that n3 − n
is divisible by 6.
Since n3 − n is divisible by 6, (n + 1)3 − (n + 1) is divisible by 6 as well if and only if the
difference
is divisible by 6 too. As shown above, in the inductive step for the first proof, this difference is
à !
2 n2 + n
3(n + n) = 6
2
162
10.2 Limits and Derivatives (Review of Math 249 or 251)
10.2.1 Solution for Exercise #1(c) in Section 3.6
This limit has the form
f (x)
lim
x→0 g(x)
for differentiable functions f (x) = x and g(x) = cos x − 1, such that lim f (x) = lim g(x) = 0.
x→0 x→0
L’Hôpital’s rule can be used in this case (and there’s no obvious common factor of f (x) and g(x)
to be cancelled out first).
In this case f 0 (x) = 1 and g 0 (x) = − sin x, so, by l’Hôpital’s rule,
f (x) f 0 (x) 1
lim = lim 0 = lim − .
x→0 g(x) x→0 g (x) x→0 sin x
However, if x is small and positive then so is sin x, so that − sin1 x is large and negative, and the
limit approaches −∞ as x approaches zero “from above” (or, “from the right”). It’s easily argued
(in pretty much the same way) that the limit approaches +∞ as x approaches zero “from below”
(or, “from the left”).
Therefore − sin1 x doesn’t have a limit as x approaches zero, so the limit you were asked to try
to compute in this question doesn’t exist, either.
Now, since g is differentiable at a, g is also continuous at a. Thus lim g(a + δ) = g(a), and it
δ→0
was given in the question that this value is nonzero. It follows by the sum, product, and quotient
rules for limits given in the online lecture notes that the last expression in the above derivation is
equal to
µ ¶ µ ¶ µ ¶ µ ¶
f (a + δ) − f (a) g(a + δ) − g(a)
lim · lim g(a) − lim f (a) · lim
δ→0 δ µ
δ→0
¶ µ
δ→0
¶
δ→0 δ
,
lim g(a) · lim g(a + δ)
δ→0 δ→0
163
since the limits given in the above expression all exist and the ones in the denominator are nonzero.
Now, by the definition of derivative,
f (a + δ) − f (a) g(a + δ) − g(a)
lim = f 0 (a) and lim = g 0 (a),
δ→0 δ δ→0 δ
lim g(a + δ) = g(a) since g is continuous at a, and
δ→0
since f (a) and g(a) are independent of δ. Thus the above expression is equal to
f 0 (a)g(a) − f (a)g 0 (a)
(g(a))2
as desired.
164
10.4 Solutions for Sample Tests
10.4.1 Solution for Sample Test in Section 5.1
1. Consider two algorithms, “Algorithm A” and “Algorithm B,” for the same problem. Algo-
rithm A uses 4n2 steps to solve a problem of size n while Algorithm B uses 100n steps to
solve a problem of the same size.
(a) (2 marks) For which inputs sizes (values of n) would Algorithm A be at least as fast as
Algorithm B?
Solution: Algorithm A is at least as fast as Algorithm B for input size n, for every
natural number n such that 4n2 ≤ 100n. For positive n, this inequality holds if and only
if n ≤ 25 (and the inequality clearly holds if n = 0 as well).
Thus, Algorithm A is at least as fast as Algorithm B for input size n whenever n ≤ 25.
(b) (3 marks) Suppose Algorithm A can be used to solve a problem of size s in time t on one
computer. What is the size of a problem that could be solved using the same algorithm,
on a new computer that is 100 times as fast?
Solution: Since m = 4n2 q steps are needed by the algorithm to solve a problem of
√
size n, 4 m = n , and n = 14 m = 12 m is the size of a problem that can be solved
1 2
√
using m steps (assuming 12 m is an integer).
Algorithm A uses 4s2 steps to solve a problem of size s on the original machine.
Since the new machine is 100 times as fast, at least 400s2 steps can be performed using
√ the
1
new machine in the same amount of time. As argued above, a problem of size 2 400s2
√
can be solved using the algorithm with this number of steps, and 12 400s2 = 10s.
Thus, the faster machine can be used to solve a problem that is ten times as large, in
the same amount of time.
Note: A one-line solution giving the correct answer (without the derivation) will receive
full marks for this question!
165
Since n was arbitrarily chosen, this implies that if hn = 2n + 3n and hn+1 = 2n+1 + 3n+1 then
hn+2 = 2n+2 + 3n+2 for every integer n ≥ 0, as is required to complete the inductive step.
It follows by induction on n that hn = 2n + 3n for every natural number n.
3. (10 marks) Recall that every node in a binary tree is either an internal node (if it has either
one or two children) or a leaf (if it does not have any children).
Prove that if a binary tree has exactly l leaves and i internal nodes, then l ≤ i + 1.
Solution: This result can be proved using induction on the size of the tree (that is, the
number of nodes it contains).
Basis: A tree with zero nodes has l = 0 leaves and i = 0 internal nodes. Clearly, l ≤ i + 1 in
this case.
A tree with one node has l = 1 leaf and i = 0 nodes, and it is clear that l ≤ i + 1 in this case
as well.
Inductive Step: Suppose n > 1 and that the claim is correct for all binary trees with
(strictly) fewer than n nodes.
Let T be a binary tree of size n, let TL be the left subtree of the root of T , and let TR be the
right subtree of the root of T (each of TL or TR may be empty).
If TL has size nL and TR has size nR then nL ≥ 0, nR ≥ 0, and nL + nR + 1 = n. If follows
that nL ≤ n − 1 and that nR ≤ n − 1.
Therefore, it follows by the inductive hypothesis that if TL has lL leaves and iL internal nodes,
then lL ≤ iL + 1, and it also follows by the inductive hypothesis that if TR has lR leaves and
iR internal nodes then lR ≤ iR + 1.
Since T has size strictly greater than one, the root of T is not a leaf. Therefore, T has
l = lL + lR leaves, and i = iL + iR + 1 internal nodes (since the root of T is not a node in
either TL or TR ).
It follows that
l = lL + lR
≤ (iL + 1) + (iR + 1)
= (iL + iR + 1) + 1
= i + 1,
as required (for T ). Since T was an “arbitrarily chosen” binary tree of size n, the desired
inequality holds for all binary trees of size n.
Therefore, it follows by induction on n that the claim is correct.
166
10.4.2 Solution for Sample Test in Section 5.2
x ln x
1. (4 marks) Compute lim .
x→+∞ x1.5
Solution #1: In this first solution a common factor (x, which is nonzero as x → +∞) will
be eliminated from the numerator and denominator, and then l’Hôpital’s rule will be used to
complete the derivation.
x ln x ln x
lim 1.5
= lim 0.5 (eliminating common factor x)
x→+∞ x x→+∞ x
(1/x)
= lim (by l’Hôpital’s rule)
x→+∞ 0.5x−0.5
1
= lim = 0.
x→+∞ 0.5x0.5
Solution #2: In this solution the common factor won’t be eliminated. Instead, l’Hôpital’s
rule will be used twice, in order to obtain a limit that can be computed.
x ln x 1 + ln x
lim 1.5
= lim (by l’Hôpital’s rule)
x→+∞ x x→+∞ 1.5x0.5
(1/x)
= lim (applying l’Hôpital’s rule again)
x→+∞ 0.75x−0.5
1
= lim = 0.
x→+∞ 0.75x0.5
Note: In all the cases above (in both proofs), l’Hôpital’s rule can be applied when it is, because
the numerator and denominator of the expression to which it’s applied both approach +∞
as x → +∞.
ex
(b) (3 marks) f (x) = x ln x
Solution: This derivative can be computed by applying the quotient rule, and then
applying the product rule to differentiate the denominator:
167
ex (x ln x) − ex (1 + ln x)
f 0 (x) =
(x ln x)2
xe ln x − ex ln x − ex
x
= .
x2 (ln x)2
R
3. (5 marks) Compute x2 ln x dx, and use differentiation to check that your answer is correct.
Hint: x2 ln x = f 0 (x) · g(x), for f 0 (x) = x2 and g(x) = ln x. Consider “integration by parts.”
Solution: Applying integration by parts, using f (x) = 13 x3 and g(x) = ln x as in the hint,
Z Z
2
x ln x dx = f 0 (x) · g(x) dx
Z
= f (x) · g(x) − f (x) · g 0 (x) dx (using integration by parts)
Z
1 1 3 1
= x3 ln x − x · dx
3 3 x
Z
1 1
= x3 ln x − x2 dx
3 3
1 1 3
= x3 ln x − x +C
3 9
for some (any) constant C.
Check by Differentiation: If g(x) = 13 x3 ln x − 19 x3 + C, then
à !
0 1 x3 3
g (x) = x2 ln x + − x2 + 0 = x2 ln x,
3 x 9
as desired.
168
Basis (i = 0): In this case there is only one integer j for which the identity must be checked,
namely, j = 0. If i = j = 0 then b(i, j) = b(0, 0) = 1 by definition, while
i! 0! 1
= = =1
j!(i − j)! 0!0! 1
(i + 1)!
b(i + 1, j) = for every integer j such that 0 ≤ j ≤ i + 1.
j!(i + 1 − j)!
(a) j = 0,
(b) j = i + 1, or
(c) 1 ≤ j ≤ (i + 1) − 1.
(i + 1)! (i + 1)!
= =1
j!(i + 1 − j)! 1 · (i + 1)!
(i + 1)! (i + 1)!
= =1
j!(i + 1 − j)! (i + 1)! · 1
169
Third Case (1 ≤ j ≤ (i + 1) − 1): In this final case,
so that the identity is also correct in this last case — as is required to complete the inductive
step.
170
Chapter 11
we’ll need to use either cancellation of terms or l’Hôpital’s rule to compute this limit.
Two solutions will be given (just to make it clear that there’s frequently more than one right
way to solve a problem).
In the first solution, l’Hôpital’s rule will be used. It’ll turn out that we need to use it more than
once.
f (n) f 0 (n)
lim = lim
n→+∞ g(n) n→+∞ g 0 (n)
so it isn’t clear what the limit of the ratio f 0 (n)/g 0 (n) is — but it’s possible to use l’Hôpital’s rule
171
a second time:
f (n) f 0 (n)
lim = lim
n→+∞ g(n) n→+∞ g 0 (n)
f 00 (n)
= lim 00
n→+∞ g (n)
2/n + 2 ln n/n
= lim
n→+∞ 0.75n−0.5
8 ln n + 8
= lim
n→+∞ 3n0.5
fˆ(n)
= lim ,
n→+∞ ĝ(n)
where fˆ(n) = 8 ln n + 8 and ĝ(n) = 3n0.5 — and where the fraction was simplified in the final steps
by multiplying both numerator and denominator by 4n.
We’re still not done, since
but progress is being made (at least, the numerator and denominator have become simpler) — and
it’s still correct to use l’Hôpital’s rule.
f (n) fˆ(n)
lim = lim
n→+∞ g(n) n→+∞ ĝ(n)
fˆ0 (n)
= lim 0
n→+∞ ĝ (n)
8/n
= lim
n→+∞ 1.5n−0.5
16
= lim √
n→+∞ 3 n
= 0.
√
We can now conclude by the limit test that f ∈ O(g) — that is, n(ln n)2 ∈ O(n n) — as
desired.
This first solution used a combination of applications of l’Hôpital’s rule and simplifications.
If simplification hadn’t been used between applications of l’Hôpital’s rule, then the limit to be
computed would have become more and more complicated, instead of simpler, and it’s unlikely that
the limit would ever have been computed.
In the second solution we’ll start by using cancellation, and then we’ll use l’Hôpital’s rule after
√
that. This time, let fˆ(n) = (ln n)2 and let ĝ(n) = n = n0.5 . In the following derivation, we’ll be
able to use l’Hôpital’s rule to compute the limit of fˆ(n)/ĝ(n), because
172
Now
f (n) n(ln n)2
lim = lim √
n→+∞ g(n) n→+∞ n n
nfˆ(n)
= lim
n→+∞ nĝ(n)
fˆ(n)
= lim
n→+∞ ĝ(n)
fˆ0 (n)
= lim 0
n→+∞ ĝ (n)
(2 ln n)/n
= lim
n→+∞ 0.5n−0.5
4 ln n
= lim
n→+∞ n0.5
f¯(n)
= lim ,
n→+∞ ḡ(n)
f¯0 (n)
= lim 0
n→+∞ ḡ (n)
4/n
= lim
n→+∞ 0.5n−0.5
8
= lim √
n→+∞ n
= 0.
We can now conclude that f ∈ O(g), as desired.
In the instructor’s opinion, the second solution is the better of the two, because it begins with
a simpler technique (which replaces the first application of l’Hôpital’s rule, in the first solution)
and leaves a slighter easier problem to be solved. The difference between the solutions would have
been more dramatic — making the second solution seem even better — if the common factor to
be eliminated from f (n) and g(n) had been a higher power of n (say, n2 ) — for, then, a single
application of cancellation would have replaced several applications of l’Hôpital’s rule.
173
so that l’Hôpital’s rule can be used to compute the limit as n approaches +∞ of fˆ(n)/ĝ(n).
The limit of the ratio of the functions we wish to compare is
n2 ln n (n ln n)fˆ(n)
lim = lim
n→+∞ n(ln n)2 n→+∞ (n ln n)ĝ(n)
fˆ(n)
= lim
n→+∞ ĝ(n)
fˆ0 (n)
= lim 0
n→+∞ ĝ (n)
1
= lim
n→+∞ 1/n
= lim n
n→+∞
= +∞.
It follows by the limit test for Ω(f ) that n2 ln n ∈ Ω(n(ln n)2 ), as required.
Note that (as in the solutions for Exercise #2) it would also have been possible to start by using
l’Hôpital’s rule, instead of cancelling out a common factor first. However — as you’ll discover, if you
try this approach — the resulting solution would have been longer and somewhat more complicated
than the one given here.
Therefore, if c = 112 and N = 1, then these are clearly positive constants, and
Note: Lots of other choices could have been made for the constants c and N , as well.
For example, if the constant N = 4 was used then we could have taken advantage of the fact
that, for n ≥ 4,
1 1
3n2 ≤ n4 , 8n ≤ n4 , and 100 ≤ n4
2 2
so that n4 + 3n2 + 8n + 100 ≤ 3n4 if n ≥ 4. In other words we could have chosen N = 4 and c = 3
in the above argument.
How small could you have chosen c to be, using N = 5?
174
Proof. It is sufficient to exhibit a pair of asymptotically positive functions f and g such that
f 6∈ O(g) and g 6∈ O(f ). One such pair was used in examples in Chapter 6 — let
(
2 n if n is odd,
f (n) = n and g(n) =
n3 if n is even.
These total functions are clearly asymptotically positive: f (n) > 0 and g(n) > 0 for every
integer n ≥ 1.
Suppose that f ∈ O(g); then, by the definition of “O(g),” there must exist constants c > 0 and
N ≥ 0 such that
since n > 0 and n − c > 0. That is, f (n) > cg(n) for some integer n > N , which contradicts
inequality (11.1). Thus, f 6∈ O(g).
Now suppose, instead, that g ∈ O(f ); then, by the definition of “O(f ),” there must exist
constants c0 > 0 and N 0 ≥ 0 such that
since n > 0 and n − c0 > 0. That is, g(n) > c0 f (n) for some integer n > N 0 , which contradicts
inequality (11.2). Thus, g 6∈ O(f ).
Since f 6∈ O(g) and g 6∈ f , this pair of functions provides a counterexample that proves that
the given claim is false.
Note that many other functions could have been used in this proof; these were chosen because
they’d been discussed already.
Proof. It is sufficient to give two asymptotically positive functions f and g such that f ∈ O(g) and
f∈/ Θ(g) but such that f ∈ / o(g) as well.
Let
(
n if n is even,
f (n) = and g(n) = n2 .
n2 if n is odd,
Since n ≤ n2 for all n ≥ 1 it is clear that if c = 1 and N = 1 then c and N are positive constants,
and that f (n) and g(n) are both defined, and f (n) ≤ cg(n), for every integer n ≥ N . It follows by
the definition of “O(g)” that f ∈ O(g).
175
Suppose (in order to obtain a proof by contradiction) that f ∈ Θ(g). Then it follows by the
definition of Θ(g) that f ∈ Ω(g) as well, so that, by the definition of Ω(g), there exist constants
c0 > 0 and N 0 such that f (n) and g(n) are both defined, and f (n) ≥ c0 g(n), for every n ≥ N 0 .
Now consider any even integer n such that n > max(N 0 , 1/c0 ); since n > N 0 , f (n) ≥ c0 g(n), so
that
f (n) − c0 g(n) ≥ 0.
On the other hand, since g(n) is positive and n > 1/c0 , c0 > 1/n, and since n is even,
1. For all asymptotically positive functions f and g, if f ∈ O(g) then g ∈ Ω(f ), and
176
and we will prove these two subclaims separately in order to establish the original claim.
Proof of First Subclaim: Let f and g be asymptotically positive functions and suppose f ∈ O(g).
Then there exist constants c > 0 and N such that f (n) and g(n) are both defined and
f (n) ≤ cg(n) for every integer n ≥ N . (11.3)
Let c0 = 1/c and let N 0 = N ; then c0 and N 0 are constants, c0 > 0 (since c is positive), and (dividing
both sides of inequality (11.3) by c and switching sides), f (n) and g(n) are both defined and
g(n) ≥ c0 f (n) for every integer n ≥ N 0 .
If follows by the definition of Ω(f ) that g ∈ Ω(f ). Now, since f and g were “arbitrarily chosen”
asymptotically positive functions such that f ∈ O(g), this proves the first subclaim.
Proof of Second Subclaim: Let f and g be asymptotically positive functions and suppose g ∈ Ω(f ).
Then there exist constants c > 0 and N such that f (n) and g(n) are both defined and
g(n) ≥ cf (n) for every integer n ≥ N . (11.4)
Let c0 = 1/c and let N 0 = N ; then c0 and N 0 are constants, c0 > 0, and (dividing both sides of
inequality (11.4) by c and switching sides), f (n) and g(n) are both defined and
f (n) ≤ c0 g(n) for every integer n ≥ N 0 .
If follows by the definition of O(g) that f ∈ O(g). Now, since f and g were “arbitrarily chosen”
asymptotically positive functions such that g ∈ Ω(f ), this proves the second subclaim.
Since both subclaims are true, the original claim is true as well.
Proof. Let f , g, and h be arbitrary asymptotically positive functions such that f ∈ O(h) and
g ∈ O(h).
Since f ∈ O(h) it follows by the definition of “O(h)” that there exist constants c1 > 0 and N1
such that f (n) and h(n) are both defined, and f (n) ≤ c1 h(n), for every integer n ≥ N1 .
Since g ∈ O(h), it also follows by the definition of “O(h)” that there exist constants c2 > 0 and
N2 ≥ 0 such that g(n) and h(n) are both defined, and g(n) ≤ c2 h(n), for every integer n ≥ N2 .
Now, let N = max(N1 , N2 ) and let c = c1 + c2 . Clearly N is a constant since N1 and N2 are
both constants, and c is a positive constant, since c1 and c2 are both positive constants.
If n is any integer such that n ≥ N then (by construction of N ), n ≥ N1 and n ≥ N2 as well.
Therefore (f + g)(n) = f (n) + g(n) is defined, since f (n) and g(n) are both defined, and h(n)
is defined as well.
Furthermore,
(f + g)(n) = f (n) + g(n)
≤ c1 h(n) + c2 h(n)
= (c1 + c2 )h(n)
= ch(n).
177
It therefore follows by the definition of “O(h)” that f + g ∈ O(h).
Since f , g, and h were arbitrarily chosen asymptotically positive functions such that f ∈ O(h)
and g ∈ O(h), it follows that if f ∈ O(h) and g ∈ O(h) then f + g ∈ O(h), for all asymptotically
positive functions f , g, and h, as required.
For each of the following pairs of functions f (n) and g(n) say which one of these claims is
correct. You do not need to prove your answer.
1.5n
(e) f (n) = n1000 , g(n) = n2
Answer: (ii) f (n) ∈ o(g(n))
Proof. The limit test for Ω(f ) will be used to establish this result.
Let f (n) = n and let g(n) = ln n. Then n2 = nf (n) and n ln n = ng(n). Cancellation,
followed by l’Hôpital’s rule, can be used to compute the desired limit. Note that
178
so that l’Hôpital’s rule is used correctly in the following derivation:
2
lim n = lim nf (n)
n→+∞ n ln n n→+∞ ng(n)
= lim f (n)
n→+∞ g(n)
0 (n)
= lim fg0 (n)
n→+∞
= lim 1
n→+∞ 1/n
= lim n
n→+∞
= +∞.
Note: Since n ≥ ln n for every integer n ≥ 1, n2 ≥ n ln n for all n ≥ 1 as well, and the claim
could also have been proved using the definition of “Ω(n ln n)” (using the constants c = 1 and
N = 1).
3. (10 marks — 5 marks for each part) Say whether each of the following claims is true or false,
and prove your answer.
(a) For every function f such that f (n) is defined and f (n) > 0 for all n ∈ N, f ∈ Θ(f ).
Proof. Let f be any function such that f (n) is defined and strictly greater than 0 for all
n ∈ N. Then
f (n)
lim = lim 1 = 1.
n→+∞ f (n) n→+∞
Since f is asymptotically positive, it follows that f ∈ Θ(f ) (by the limit test for Θ(f )).
Note: This could also have been proved using the definition of “Θ(f (n)),” since it is
clear that cL f (n) ≤ f (n) ≤ cU f (n) for all n ≥ N , if you choose cL = cU = 1 and N = 0.
(b) For all functions f and g such that f (n) and g(n) are defined for all n ∈ N, and f (n) and
g(n) are strictly greater than 0 whenever n ≥ N for some integer N (so that f and g
are asymptotically positive), if f ∈ Ω(g) then f ∈ ω(g).
179
Proof. If is sufficient to give a pair of functions f and g such that both f and g are
asymptotically positive, f ∈ Ω(g), and f 6∈ ω(g) (and, of course, to prove that these
claims about f and g are true).
Let f (n) = g(n) = n for all n ∈ N. Then, clearly, f and g are both asymptotically
positive (f (n) = g(n) = n > 0 for all n ≥ 1). Since f = g, and g(n) > 0 for all n > 0,
Since f and g are asymptotically positive, and this limit exists and is a constant that is
greater than zero, it follows by the limit test for Θ(f ) that f ∈ Ω(g).
Since the limit is finite it follows by the limit test for ω(f ) that f 6∈ ω(g).
Thus, this pair of functions serve as a counterexample that disproves the claim.
Note: Any other pair of asymptotically positive functions f and g such that f ∈ Ω(g)
but f 6∈ ω(g) could have been used as a counterexample in order to disprove this claim,
as well.
For each of the following pairs of functions f (n) and g(n) say which one of these claims is
correct. You do not need to prove your answer.
(a) f (n) = 1 2
10 n , g(n) = 20n Answer: (iv) f (n) ∈ ω(g(n)).
(f) f (n) = 1
1000 (ln n)
1000 , g(n) = n1/1000 Answer: (ii) f (n) ∈ o(g(n)).
180
2. (5 marks) Prove that 2n + 3 ln n ∈ Θ(n).
Proof. The limit test for “big Theta” will be applied. Let f (n) = 2n + 3 and g(n) = n, and
note that
so that l’Hôpital’s rule can be applied to compute the limit as n approaches +∞ of f (n)/g(n).
f (n) f 0 (n)
lim = lim
n→+∞ g(n) n→+∞ g 0 (n)
2 + (3/n)
= lim
n→+∞ 1
= 2.
Since the above limit is a positive constant, it follows by the limit test that 2n + 3 ln n ∈
Θ(n).
3. (6 marks) Say whether the following claim is true or false, and then prove your answer.
Claim: For all asymptotically positive functions f and g, if f ∈ o(g) then g ∈ ω(f ).
f (n) ≤ 1
c1 g(n)
181
Proof #2: Application of Limit Tests
Recall that the “limit tests” for “little-oh” and “little-omega” were necessary as well as
sufficient conditions, for asymptotic relations to hold (unlike the limit tests for “big-Oh,” et
cetera).
Suppose now that f and g are arbitrarily chosen asymptotically positive functions such that
f ∈ o(g). Then, by the limit test for o(g),
f (n)
lim = 0.
n→+∞ g(n)
Note, as well, that for sufficiently large n, f (n) and g(n) are both defined and
f (n)
> 0,
g(n)
since the functions f and g are both asymptotically positive.
It follows (by the definition of “limit”) that, for every real number M > 0, there exists an
integer N ≥ 0 such that
f (n) 1
0< < for every integer n ≥ N ;
g(n) M
otherwise, it wouldn’t be true that
f (n)
lim = 0.
n→+∞ g(n)
However, this implies that for every real number M > 0, there exists an integer N ≥ 0
(namely, the same one as above) such that
g(n)
>M for every integer n ≥ N ,
f (n)
and it follows (by the definition of “limit”) that
g(n)
lim = +∞.
n→+∞ f (n)
4. Suppose now that you have two algorithms, A and B, that solve the same problem. The worst
case running time of algorithm A (for input size n) is TA (n), and the worst case running time
of algorithm B is TB (n). TA ∈ o(TB ).
(a) (2 marks) Give the definition for the “worst case running time” of an algorithm.
Solution: This is Definition 6.1 on page 64.
182
(b) (2 marks) Give the definition for “f ∈ o(g),” for asymptotically positive functions f
and g.
Answer: This is Definition 6.6 on page 66.
(c) (1 mark) Does the above statement about algorithms A and B imply that algorithm A
will always solve the problem more quickly than algorithm B? That is, this does imply
that algorithm A will solve the problem more quickly than algorithm B, on every possible
input? Your answer should be either “Yes” or “No.”
Answer: No, the above statement does not imply this.
(d) (3 marks) Say, in your own words, what the the above statement does imply about the
relative performance of the two algorithms. Be as precise as you can (but try to do
something different than just restating your answer for the first parts of this question).
Answer: This implies that for every sufficiently large integer n, there exists at least
one input I of size n such that the time used by the algorithm B on input I is much
larger than the time TA (n) spent by algorithm A on any input of size n (that is, the
time spent by algorithm A on inputs of size n in the worst case). Thus TB (n), the time
spent by algorithm B on inputs of size n in the worst case, is much larger than TA (n),
the time spent by algorithm A on inputs of size n in the worst case, as well.
In particular, for any positive constant ² > 0, TTBA (n)
(n) < ² if n is sufficiently large.
Note, though, that
• this does not necessarily imply that TTBA (n)
(n) < ² when n is small, and
• this does not necessarily imply that algorithm A runs more quickly than algorithm B
on “most” inputs: It sometimes happens that the “expected” running time of algo-
rithm A on inputs of size n (defined using some plausible probability distribution
for the inputs of size n) is actually larger than the expected running time of algo-
rithm B on inputs of size n (defined using the same probability distribution), even
though the above statement about worst case running times holds.
Note: You certainly wouldn’t need to make all the above points in order to get full
marks for this last part of the question. On the other hand, you’d lose some marks if
you made statements that are false (such as, statements that contradict the information
given here).
183
11.2 Summations
11.2.1 Solutions for Selected Exercises
Solution for Exercise #1(d) in Section 7.12
Following the hint for this problem, we’ll begin by trying to express the function whose sum is
being computed in the form
c c
− .
(2i + 1)2 (2i − 1)2
This is clearly equal to
c((2i − 1)2 − (2i + 1)2 ) −8ci
= ,
(2i + 1) (2i − 1)
2 2 (2i + 1)2 (2i − 1)2
and we want to equate it with
i
.
(2i + 1)2 (2i − 1)2
This can be accomplished by setting c = − 18 .
Now, we know that
X
n Xn µ µ ¶ µ ¶¶
i 1 1 1 1
= − +
i=1
(2i + 1) (2i − 1)
2 2
i=1
8 (2i + 1)2 8 (2i − 1)2
X
n
= (f (i + 1) − f (i)),
i=1
where
µ ¶
1 1
f (j) = − .
8 (2j − 1)2
It should now be apparent that this is a telescoping sum, so we can continue by simply writing
down its closed form and simplifying:
X
n
i Xn
= (f (i + 1) − f (i))
i=1
(2i + 1)2 (2i − 1)2 i=1
= f (n + 1) − f (1)
µ ¶ µ ¶
1 1 1 1
=− +
8 (2n + 1)2 8 12
1 1 1
= − · .
8 8 (2n + 1)2
Several of the methods for solving summations can be applied to answer this question, so several
solutions will be presented (and compared) below.
184
Solution #1: Splitting the Sum and Bounding Terms. We’ll start by “bounding the terms”
and inspecting the resulting estimates. Occasionally, this is sufficient to solve a problem without
“splitting the sum,” so we’ll try this first. Since
f (x) = x4 ln x
is a nondecreasing function on the positive real numbers and we are trying to bound
X
n X
n
i4 ln i = f (i),
i=1 i=1
This is not good enough, since the lower bound, 0, clearly does not grow at the same rate as the
upper bound, n5 ln n.
Since the simplest approach didn’t work we’ll continue by splitting the sum into two pieces, and
bounding each piece. The function f (n) grows reasonably slowly with n (it’s more like a polynomial
than an exponential), so we’ll split the sum down the middle, as
X
n X
m X
n
i4 ln i = i4 ln i + i4 ln i for m = b n2 c.
i=1 i=1 i=m+1
Let
X
m X
n
SL = i4 ln i and SU = i4 ln i
i=1 i=m+1
for m as above. Then we can bound terms for both sums, to obtain the inequalities
¡ ¢4 ¡ ¢
0 ≤ SL ≤ b n2 c · b n2 c ln b n2 c ,
and
¡ ¢ ¡ ¢4 ¡ ¢ ¡ ¢
n − b n2 c · b n2 c + 1 ln b n2 c + 1 ≤ SU ≤ n − b n2 c · n4 ln n.
185
Since SL ≥ 0 it follows that S = SL + SU ≥ 64 n ln n if n ≥ 4 as well. Combining this with the
1 5
upper bound that we obtained without splitting the sum, we see that
X
n
1 5
64 n ln n ≤ i4 ln i ≤ n5 ln n if n ≥ 4,
i=1
f (i) = i4 ln i
for a constant C.
Therefore, let F (t) = 15 t5 ln t − 25 t ; then F 0 (t) = f (t) = t4 ln t.
1 5
Now, if we tried to approximate by integrals, starting with the original sum, then we’d (seem-
ingly) obtain the bounds
Z n X
n Z n+1
f (t) dt ≤ f (i) ≤ f (t) dt,
0 i=1 1
that is,
X
n
F (n) − F (0) ≤ i4 ln i ≤ F (n − 1) − F (1)
i=1
for F (x) as above. Unfortunately F (0) is not defined (it has “ln 0” as a factor), so this is of no use.
In order to avoid this problem we’ll split away the first term of the sum, to be considered
separately, and bound the rest instead:
Z n X
n Z n+1
f (t) dt ≤ f (i) ≤ f (t) dt,
1 i=2 2
186
that is,
X
n
F (n) − F (1) ≤ f (i) ≤ F (n + 1) − F (2).
i=2
so that
X
n
F (n) − F (1) ≤ f (i) ≤ F (n + 1) − F (2)
i=1
as well.
Now, this implies that
X
n
f (i) ≥ F (n) − F (1)
i=1
= 15 n5 ln n − 1 5
25 n − 15 15 ln 1 + 1 5
25 1
= 15 n5 ln n − 1 5
25 n + 1
25 ,
and
X
n
f (i) ≤ F (n + 1) − F (2)
i=1
= 15 (n + 1)5 ln(n + 1) − 1
25 (n + 1)5 − 1
5 · 25 ln 2 + 1
25 · 25 .
Now, it certainly isn’t immediately clear from the above, but it can be shown (using calculus) that
this upper bound has the form
1 5
5 n ln n + l(n)
Comparison of Solutions. It’s certainly possible to improve the bounds that were obtained
by “splitting the sum and bounding terms.” For example, by adding together the upper bounds
derived for SL and SU , above, one can obtain a bound that’s slightly more than half (actually
approximately 1732 of) the upper bound that is given above.
You could also split the sum into a larger number of pieces, and bound each separately, to
obtain upper and lower bounds for the total that are even closer together.
However, the method of “approximating by integrals” still produces upper and lower bounds
that are closer together than anything you’re likely to obtain by splitting the sum and bounding
terms, no matter how many pieces you use when splitting the sum. In particular, the difference
187
between the upper and lower bounds, obtained using approximation by integrals, is in o(n5 ln n),
while the sum itself is in Θ(n5 ln n).
That is, splitting the sum and bounding terms only allowed us to conclude that
X
n
i4 ln i ∈ Θ(g(n)) for g(n) = n5 ln n;
i=1
and you aren’t ever likely to get an approximation this fine using the first technique.
Of course, one advantage of the first method is its generality: You can apply it to bound sums
of functions that aren’t “nondecreasing,” or that are difficult to integrate.
that didn’t include an exact solution for the recurrence. “Completing and confirming a pattern”
can be used accomplish this.
Outline of the Method. In order to solve this problem it is necessary to prove things, namely,
that
X
n
1. i2 ≤ cn3 for some positive constant c, for all n ≥ 1;
i=1
X
n
2. i2 ≥ ĉn3 for some positive constant ĉ and for all n ≥ 1.
i=1
188
X
n
Proof that i2 ∈ O(n3 ). It is necessary and sufficient to prove the following.
i=1
X
n X
1
i2 = i2 = 1
i=1 i=1
and
cn3 = c · 13 = c
In order to complete the inductive step it is necessary to prove, using only this assumption, that
X
n+1
i2 ≤ c(n + 1)3
i=1
as well.
Now
X
n+1 X
n
i2 = i2 + (n + 1)2
i=1 i=1
≤ cn + (n + 1)2
3
by the inductive hypothesis
3 2
= cn + n + 2n + 1,
and
The desired inequality will hold if the first of these polynomials is less than or equal to the
second, and this will be the case if the respective coefficients are related in this way, that is, if
189
• c ≤ c (comparing the coefficients of n3 for the polynomials),
These aren’t all necessary to ensure that the first polynomial in n is less than or equal to the
second, but they are certainly sufficient, since n ≥ 0. These are clearly all satisfied if and only if
c ≥ 1.
X
n+1
Thus i2 ≤ c(n + 1)3 in this case.
i=1
Choice of Constant
We can now choose c to be any constant that is greater than or equal to 1 (in particular, c = 1
will do) in order to complete the proof of the claim.
as desired.
X
n
Proof that i2 ∈ Ω(n3 ). Now, the following must be proved.
i=1
X
n X
1
i2 = i2 = 1
i=1 i=1
and
ĉn3 = ĉ · 1 = ĉ
190
Inductive Step: Suppose now that n ≥ 1 and that
X
n
i2 ≥ ĉn3 .
i=1
In order to complete the inductive step it is necessary to prove, using only this assumption,
that
X
n+1
i2 ≥ ĉ(n + 1)3
i=1
as well.
Now
X
n+1 X
n
2
i = i2 + (n + 1)2
i=1 i=1
≥ ĉn3 + (n + 1)2 by the inductive hypothesis
= ĉn3 + n2 + 2n + 1,
and
The desired inequality will hold if the first of these polynomials is greater than or equal to the
second, and this will be the case if the respective coefficients are related in this way, that is, if
Again, these aren’t all necessary conditions to ensure that the first polynomial in n is greater than
or equal to the second, but they are certainly sufficient, since n ≥ 0. These are clearly all satisfied
if (and only if) ĉ ≤ 13 .
X
n+1
Thus i2 ≥ ĉ(n + 1)3 in this case.
i=1
Choice of Constant
1
We can now choose ĉ to be any positive constant that is less than or equal to 3 (in particular,
ĉ = 13 will do) in order to complete the proof of this claim.
191
Conclusion. Since
X
n X
n
i ∈ O(n )
2 3
and i2 ∈ Ω(n3 ),
i=1 i=1
it follows that
X
n
i2 ∈ Θ(n3 ),
i=1
as desired.
Note: You may use the fact that the function g(x) = x4 is an increasing function, without
proving it.
X
n
so that i4 − f (n) ∈ O(n4 ) for f (n) = 15 n5 (and this can be proved by approximating the
i=1
given sum by an integral).
192
X
n
2. (10 marks) Prove that i log2 i ∈ Θ(n2 log2 n).
i=1
X
n X
n
i log2 i ≤ M = nM = n2 log2 n.
i=1 i=1
X
n
It is also true that i log2 i = SL + SU , where
i=1
bn/2c
X X
n
SL = i log2 i, and SU = i log2 i.
i=1 i=bn/2c+1
so
bn/2c
X
SL ≥ mL = bn/2cmL = bn/2c0 = 0,
i=1
and
X
n
SU ≥ mU = (n − bn/2c) mU
i=bn/2c+1
≥ (n/2)mU
≥ (n/2)(n/2) log2 (n/2)
≥ (n2 /4)((log2 n)/2)
X
n
1 1
i log2 i = SL + SU ≥ 0 + n2 log2 n = n2 log2 n
i=1
8 8
193
Solution for Sample Test in Section 7.14.2
1. (6 marks in total; marks for each part shown below)
Each of the following summations is in a special form (for example, possibly, an arithmetic
series) that you should be able to recognize, and whose closed form you should already know.
Say way special form each summation has, and write down the exact solution of the above
summation in closed form (not just the general solution for summations of this type). It isn’t
necessary to simplify your answer.
X
n−1
(a) 3 · 6i
i=0
X
n
(b) (5i+1 ln(i + 1) − 5i ln i)
i=1
2. (1 mark) Briefly explain why you might need to find asymptotic bounds for summations in
closed form, when estimating the worst case running times of programs from source code.
Answer: Summations arise as the worst case running times (or upper bounds on them) for
while, repeat, and for loops. However, it is generally difficult to compare them to other
functions, so that equivalent expressions (or even asymptotic bounds) are more useful than
the summations are themselves.
Note: The first half of the above answer (describing the loops whose worst case running times
are expressed as summations) will be sufficient to receive full marks for this question.
194
(so, the integral on the left is the lower bound, and the integral on the right is the upper
bound).
Note: You may assume that the function f (x) = x2.5 is a nondecreasing function of x
(defined on the nonnegative reals) without having to prove it.
Answer: Let F (t) = 1 3.5
3.5 t ; then F 0 (i) = i2.5 .
X
n
It follows (using “approximation by integrals”) that i2.5 ≥ F (n) − F (0) = 1 3.5
3.5 n , so
i=1
X
n
that i2.5 ∈ Ω(n3.5 ), since 1
3.5 is a positive constant.
i=1
X
n
It also follows that i2.5 ≤ F (n + 1) − F (1) = 1
3.5 (n + 1)3.5 − 1
3.5 . Now since
i=1
1
+ 1)3.5 − 1 ³ ´3.5
3.5 (n 3.5 1 1 1 1
lim = lim 1+ + 3.5n3.5
= 3.5 ,
n→+∞ n3.5 n→+∞ 3.5 n
There are several ways that you could prove this using techniques introduced in class; each
will be acceptable (provided that the methods are used correctly).
If you get stuck, you can say what you’d need to do in order to finish (even though you
couldn’t manage to do it) in order to earn part marks.
Note: You may assume that the function f (x) = x(ln x)3 is a nondecreasing function of x
(defined on the positive reals) without proving it.
Solution: This question could be answered using several of the methods given in class, but
one was (in my opinion) much easier to use, in this case, than any of the others. A correct
solution using any of these methods will receive full marks for this question.
Approach #1: Splitting the Sum and Bounding Terms. This was almost certainly
the method from class to use, in order to answer this particular question most easily.
195
We’ll start (as usual) by bounding terms without splitting the sum. Since it’s given that the
above function f is nondecreasing,
so that
X
n X
n
n · f (1) ≤ f (i) = i(ln i)3 ≤ n · f (n).
i=1 i=1
X
n
However the above lower bound (0) isn’t tight enough to allow us to conclude that i(ln i)3 ∈
i=1
Ω(n2 (ln n)3 ), which we also need in order to finish.
Therefore we’ll split the sum in order to try to improve the lower bound. Since the function
f grows relatively slowly, we’ll split down the middle, rewriting the sum as
X
n
i(ln i)3 = SL + SU
i=1
for
X
m X
n
SL = i(ln i)3 and SU = i(ln i)3 ,
i=1 i=m+1
where m = b n2 c.
Once again, since 1 · (ln 1)3 = 0,
SL ≥ m · (1 · (ln 1)3 ) = 0.
However,
X
n X
n
SU = i(ln i)3 ≥ (m + 1)(ln(m + 1))3
i=m+1 i=m+1
= (n − m)(m + 1)(ln(m + 1))3
¡n¢
≥ 2 (m + 1)(ln(m + 1))3 since n − m ≥ n
2
¡n¢ ¡n¢ ¡ ¡ n ¢¢3
≥ 2 2 ln 2 ,
196
Simplifying the final expression and using the above bound for SL , we can conclude that
X
n
i(ln i)3 = SL + SU ≥ SU ≥ 14 n2 ((ln n) − (ln 2))3 .
i=1
X
n
so that i(ln i)3 ∈ Ω(n2 (ln n)3 ) as well.
i=1
Another way would be note that if n ≥ 4 then ln 2 ≤ 1
2 ln n, so that
³ ´3
1 2
4 n ((ln n) − (ln 2))3 ≥ 14 n2 1
2 ln n = 1 2 3
32 n (ln n) ,
so that
X
n
i2 (ln i)3 ≥ 1 2
32 n (ln n)
3
i=1
X
n
if n ≥ 4, which also implies that i(ln i)3 ∈ Ω(n2 (ln n)3 ).
i=1
X
n
In any case, once we’ve established that i(ln i)3 ∈ Ω(n2 (ln n)3 ), we can recall that we’ve
i=1
X
n
already proved that i(ln i)3 ∈ O(n2 (ln n)3 ), as well, and then conclude that
i=1
X
n
i(ln i)3 ∈ Θ(n2 (ln n)3 ),
i=1
as desired.
Note: This proof also required the fact that the function g(x) = ln x is a nondecreasing
function on the positive reals, and you could use this without proof.
You will earn a small number of bonus marks if you provided a correct proof that this is
a nondecreasing function (perhaps, by showing that its derivative is always positive) on the
positive reals, when you used this fact.
Sketch of Approach #2: Approximation by Integrals. Since it was given that the
function f (x) = x(ln x)3 is a nondecreasing function on the positive reals, this technique can
also be applied correctly here.
197
(Note, though, that this technique was to be used on another question on the quiz; therefore
the above function f was deliberately chosen to be difficult to integrate.)
Through the repeated use of “integration by parts,” it is possible to discover that if
then F 0 (i) = f (i) = i(ln i)3 . While finding F (x) in the first place isn’t easy, it should be
straightforward for you to verify that this is an antiderivative of f by differentiating to check
that F 0 (x) = f (x).
Now, the inequality that you’d probably write down next would be
X
n
i(ln i)3 ≥ F (n) − F (0),
i=1
but this is not helpful, since F (0) is undefined (it has “ln 0” as a factor).
Fortunately, 1 · (ln 1)3 = 0, so that
X
n X
n
i(ln i)3 = i(ln i)3
i=1 i=2
since F 0 (x) = f (x) and the function f (x) is nondecreasing on the set of real numbers greater
than or equal to one. Thus
X
n
i(ln i)3 ≥ F (n) − F (1) = 12 n2 (ln n)3 − 34 n2 (ln n)2 + 34 n2 (ln n) − 38 n2 + 38 .
i=1
By using either the limit test, or bounding each of the trailing terms by a small multiple of
n2 (ln n)3 when n is large (say, when n ≥ e3 ), you can use the above inequality to argue that
X
n
i(ln i)3 ∈ Ω(n2 (ln n)3 ).
i=1
and you can either use a limit test or additional algebraic manipulation (assuming n is suffi-
ciently large, say when n ≥ e3 ), to use this to prove that
X
n
i(ln i)3 ∈ O(n2 (ln n)3 ),
i=1
198
as well.
Once you’ve done this, you can finish by observing that this implies that
X
n
i(ln i)3 ∈ Θ(n2 (ln n)3 ),
i=1
as desired.
Note: Since the previous question on the test required a description of the method “approxi-
mation by integrals,” you won’t earn a large number of part marks if you sketch the method
again here — at least, not unless you managed to integrate the above function f correctly,
and got stuck for some other reason!
X
n
i(ln i)3 = 1 · (ln 1)3 = 0
i=1
and
so the desired inequality holds in this case for any choice of the constant c.
199
Then
X
n+1 X
n
i(ln i)3 = i(ln n)3 + (n + 1)(ln(n + 1))3
i=1 i=1
≤ cn2 (ln n)3 + (n + 1)(ln(n + 1))3 by the inductive hypothesis
≤ cn2 (ln(n + 1))3 + (n + 1)(ln(n + 1))3 since cn2 ≥ 0 and (ln(n + 1))3 ≥ (ln n)3
= (cn2 + n + 1)(ln(n + 1))3
≤ (cn2 + 2cn + c)(ln(n + 1))3 provided that 2c ≥ 1 and c ≥ 1
2 3
= c(n + 1) (ln(n + 1)) as desired.
It’s easily checked that all of the above constraints on c are satisfied as long as we choose
c ≥ 1. In particular, c = 1 will do.
Therefore
X
n
i(ln i)3 ≤ cn2 (ln n)3
i=1
The proof of the second claim is more difficult, because it isn’t obvious how to replace ln(n+1)
by something involving ln n, when you are trying to establish the inequality in the other
direction.
If you did everything above correctly, began a similar proof of the second claim and got stuck,
and then explained that you would ideally finish by completing the second proof by induction,
choosing a positive constant ĉ satisfying all the identified constraints, and then concluding
that
X
n
i(ln i)3 ∈ Ω(n2 (ln n)3 )
i=1
then you can expect to receive at least seven out of the possible ten marks for this question.
It is possible to complete this question using this technique — but it isn’t easy. Here is one
way to do this, which I couldn’t possibly expect you to have discovered when writing the test!
Lemma: If n ≥ 2 then ln n ≥ ln(n + 1) − n1 .
This lemma can be proved by inspecting the Taylor series for h(x) = ln(1 + x), and noting
that
³ ´
ln(n + 1) − ln n = ln 1 + 1
n .
200
Here is a proof of the second claim that uses this.
Basis: The case n = 1 is the same as it is for the first proof: One ends up with the inequality
0 ≥ 0, which is satisfied for any choice of the constant ĉ.
If n = 2 then
X
n
i(ln i)3 = 2(ln 2)3
i=1
and
ĉn2 (ln n)3 = 4ĉ(ln 2)3 ,
X
n
so i(ln i)3 ≥ ĉn2 (ln n)3 in this case provided that ĉ ≤ 12 .
i=1
201
11.3 Recurrences
11.3.1 Solutions for Selected Exercises
Solution for Exercise #1(c) in Section 8.10
Derivation of a Pattern. If n is a power of two (as is given in the question), then so is n2
provided that n ≥ 2, and b n2 c = n2 in this case. Thus, if n is a power of two and T (n) is defined by
the recurrence given in the question, then
¡n¢
T (n) = 4T 2 + n3 if n ≥ 2,
³ ¡n¢ ¡ n ¢3 ´
= 4 4T 4 + 2 +n 3
if n ≥ 4,
1 ³ ´
X
¡n¢ i
= 42 T 4 + n3 1
2
i=0
³ ¡n¢ ¡ n ¢3 ´ 1 ³ ´
X i
= 42 4T 8 + 4 + n3 1
2 if n ≥ 8,
i=0
2 ³ ´
X
¡n¢ i
= 43 T 8 + n3 1
2 ...
i=0
At this point, or after you perform one or two more iterations, you might guess that if k ≥ 0
and n is a power of two such that n ≥ 2k , then
³ ´ X³
k−1 ´i
T (n) = 4k T n
2k
+ n3 1
2 .
i=0
³ ´ X³
k−1 ´i
T (n) = 4k T n
2k
+ n3 1
2 .
i=0
as desired.
Inductive Step: Suppose now that k ≥ 0 and that
³ ´ X³
k−1 ´i
T (n) = 4k T n
2k
+ n3 1
2 .
i=0
202
It is necessary (and sufficient) to prove that if n is a power of two and n ≥ 2k+1 then
³ ´ (k+1)−1 ³
X ´i
T (n) = 4k+1 T 2k+1
n
+ n3 1
2 .
i=0
Suppose, then, that n is a power of two and that n ≥ 2k+1 . Then n ≥ 2k as well, so
³ ´ X³
k−1 ´i
T (n) = 4k T n
2k
+ n3 1
2 .
i=0
Therefore,
³ ´ X³
k−1 ´i
T (n) = 4k T n
2k
+ n3 1
2 by the inductive hypothesis
i=0
µ ³ ´ ³ ´3 ¶ X³
k−1 ´i
=4 k
4T 2k+1
n
+ n
2k
+ n3 1
2
i=0
³ ´ X³
k−1 ´i
n3
= 4k+1 T n
2k+1
+ 2k
+ n3 1
2
i=0
³ ´ (k+1)−1 ³
X ´i
= 4k+1 T 2k+1
n
+ n3 1
2 , as desired,
i=0
as desired.
203
Application of a Pattern. Since n is a power of two, n = 2log2 n and log2 n is a nonnegative
integer, so we can choose k = log2 n and apply the pattern that’s just been verified. In this case,
³ ´ (log2 n)−1 ³
X ´i
log2 n n 3 1
T (n) = 4 T 2log2 n
+n 2 (applying the pattern)
i=0
(log2 n)−1 ³ ´i
X
= n2 T (1) + n3 1
2
i=0
³ ´log2 n
1− 1
2 3 2
=n +n (using the closed form for a geometric series)
1− 1
2
à !
1− 1
= n2 + n3 1
n
2
= n2 + 2n3 − 2n2
= 2n3 − n2 .
This isn’t the only approach you could take to solve this problem. As an additional exercise,
simplify the recurrence by performing a “change of variable,” expressing the function in terms of
k = log2 n, and then try to apply the iteration method after that. You should find that the resulting
solution is simpler than the one given here.
and
³ ´
T (n + 1) = 4T b n+1
2 c + (n + 1) .
3
2 c ≤ n, and either
Furthermore, since n ≥ 1, 1 ≤ b n+1
b n+2
2 c=b 2 c
n+1
204
(if n is odd), or
2 c=b 2 c+1
b n+2 n+1
because b n+2
2 c = b 2 c, and in the second case
n+1
³ ´ ³ ´ ³ ´
T b n+2
2 c =T b 2 c+1 ≥T b 2
n+1 n+1
205
Thus
1 if n = 2,
U (n) = ³ ´
4U b n+1
2 c + (n − 1)3 if n ≥ 3.
Thus
1 if n = 0,
V (n) = ³ ´
4V b n−1
2 c + (n + 1)3 if n ≥ 1.
Establishing the Upper Bound. It’s sufficient to prove the following in order to show that
T (n) ∈ O(n3 ).
Claim. There exists a positive constant c such that T (n) ≤ cn3 for every integer n ≥ 1.
206
Since n ≥ 1, n + 1 ≥ 2, so that
³ ´
T (n + 1) = 4T b n+1
2 c + (n + 1)
3
by the definition of T
2 c + (n + 1)
≤ 4cb n+1 3 3 by the inductive hypothesis, since 1 ≤ b n+1
2 c≤n
³ ´3
≤ 4c n+1
2 + (n + 1)3
¡c ¢ ³ ´3
(n+1)3
= 2 + 1 (n + 1)3 since n+1
2 = 8
Establishing the Lower Bound. It’s sufficient to prove the following claim in order to establish
that T (n) ∈ Ω(n3 ).
Claim. There exists a positive constant ĉ such that T (n) ≥ ĉn3 for every integer n ≥ 1.
2 c + (n + 1)
≥ 4ĉb n+1 3 3 by the inductive hypothesis, since 1 ≤ b n+1
2 c≤n
≥ 0 + (n + 1)3 since n ≥ 1, so that b n+1
2 c≥0
≥ ĉ(n + 1)3 provided that ĉ ≤ 1
Conclusion. Since T (n) ∈ O(n3 ) and T (n) ∈ Ω(n3 ), T (n) ∈ Θ(n3 ), as desired.
207
Solution for Exercise #5(b) in Section 8.10
In this question, you were asked to use the master theorem to find an asymptotic bound in closed
form for T (n), where
(
1 if n = 1,
T (n) = ¡ ¢
4T d n2 e + n2 if n ≥ 2.
Solution Using the “Simplified” Master Theorem. The recurrence has the form presented
in the master theorem; it corresponds to the choice of constants a = 4, b = 2, c = 1, and the
function f (n) = n2 .
In addition f has the form that you need in order to apply the “simplified” version of the
theorem: f (n) ∈ Θ(nα (log n)β ), for α = 2 and β = 0.
Now since logb a = log2 4 = 2, α = logb a and β = 0 in this case, so that the second case covered
by the master theorem applies.
Therefore, T (n) ∈ Θ(nlogb a log2 n) = Θ(n2 log2 n).
Solution Using the Original (Corrected) Master Theorem. The previous solution is com-
pletely satisfactory. However, the problem can be solved using the original version of the master
theorem too.
In order to do this you’d start by recognizing that the recurrence has the required form and
identifying the constants a, b, and c, and the function f (n), as above.
Once again, logb a = log2 4 = 2, so
f (n) n2
lim = lim
n→+∞ nlogb a n→+∞ n2
= lim 1
n→+∞
= 1,
Attempted Solution Using the “Simplified” Version. The recurrence has the form pre-
sented in the master theorem; it corresponds to the choice of constants a = 4, b = 2, c = 1, and
the function f (n) = n2 log2 n.
In addition, f has the form that you need in order to try to apply the “simplified” version of
the theorem: f (n) ∈ Θ(nα (log n)β ), for α = 2 and β = 1.
208
Now since logb a = log2 4 = 2, α = logb a, so that the first and third cases of the simplified
theorem are not applicable. However, β 6= 0, so that the second case covered by the simplified
theorem is not applicable, either.
Therefore, the simplified version of the master theorem cannot be used to solve this problem.
Attempted Solution Using the Original Theorem. Since a = 2, b = 4, and f (n) = n2 log2 n,
f (n) n2 log2 n
lim log a
= lim
n→+∞ n b n→+∞ n2
= lim log2 n
n→+∞
= +∞.
Therefore it follows by the limit test that f (n) ∈ ω(nlogb a ). This implies that f (n) is not in
O(n(logb a)−² ) for any positive constant, so that the first case is not applicable, and it also implies
that f (n) is not in Θ(nlogb a ), so that the second case is not applicable either.
However, let ² be any positive constant; then
f (n) n2 log2 n
lim = lim
n→+∞ n(logb a)+² n→+∞ n2+²
log2 n
= lim
n→+∞ n²
(log2 e) ln n
= lim
n→+∞ n²
(log2 e)/n
= lim by l’Hôpital’s rule
n→+∞ ²n²−1
1
= log²2 e lim ²
n→+∞ n
= 0,
since ² > 0. It follows that f (n) ∈ o(n(logb a)+² ), and therefore that f (n) is not in Ω(n(logb a)+² ), for
every positive constant ².
Therefore the third case of the (original) master theorem is not applicable either.
Thus the (original version of the) master theorem cannot be applied in order to solve this
problem, either.
An Optional Exercise. Use the substitution method to confirm that T (n) ∈ Θ(n2 (log2 n)2 ).
209
Solution Using the “Simplified” Master Theorem. The recurrence has the form presented
in the master theorem; it corresponds to the choice of constants a = 4, b = 2, c = 1, and the
function f (n) = n5 .
In addition, f has the form that you need in order to apply the “simplified” version of the
theorem: f (n) ∈ Θ(nα (log n)β ), for α = 5 and β = 0.
In this case, logb a = log2 4 = 2, so α > logb a, and the third case of the simplified master
theorem is applicable.
Therefore, T (n) ∈ Θ(f (n)) = Θ(n5 ).
Solution Using the “Original” Master Theorem. The above proof is completely acceptable,
but the problem can be solved using the original version of the master theorem too.
The argument presented below is a reasonably “short” version, in the sense that it doesn’t
include a use of a limit test to disqualify cases (in order to determine which case is the only one
that could apply). See the solution for Exercise #6(b), above, for an example of this.
We’d begin, as above, by noting that the recurrence has the required form, and that it corre-
sponds to the choice of constants a = 4, b = 2, c = 1, and the function f (n) = n5 .
Let ² = 1. Then (logb a) + ² = (log2 4) + 1 = 3, so
f (n) n5
lim = lim
n→+∞ n(logb a)+² n→+∞ n3
= lim n2
n→+∞
= +∞,
for all sufficiently large n. Since f (n) is asymptotically positive (indeed, in this particular problem,
f (n) > 0 whenever n > 0), this is equivalent to the condition that
¡ ¢
af nb
≤d<1
f (n)
210
so the regularity condition is satisfied if we choose d = 18 . (It’s also satisfied if we choose d to be
any other positive constant such that 18 ≤ d < 1, as well.)
Since all the required conditions for it are satisfied, the third case given in the master theorem
is applicable.
Therefore, T (n) ∈ Θ(f (n)) = Θ(n5 ).
This is a linear recurrence with constant coefficients, so you should try to apply Theorem 8.9
(on page 141) to solve this problem.
The above recurrence has characteristic polynomial
x3 − x2 − x + 1
(note the signs of the coefficients of x2 , x, and 1!). It was given in the question that 1 is a root
of this polynomial, and this implies that the polynomial is divisible by x − 1. Indeed, if we divide
the characteristic polynomial by x − 1 and then use the binomial theorem to factor the resulting
quotient, we will discover that
x3 − x2 − x + 1 = (x − 1)(x2 − 1)
= (x − 1)(x − 1)(x + 1)
= (x + 1)(x − 1)2 .
Thus the characteristic polynomial has two roots, β1 = −1 (with multiplicity ν1 = 1) and β2 = 1
(with multiplicity ν2 = 2). According to Theorem 8.9, it follows that
(
c2,1 n + c2,0 + c1,0 if n is even,
T (n) = c1,0 β1n + (c2,1 n + c2,0 )β2n n
= c1,0 (−1) + c2,1 n + c2,0 =
c2,1 n + c2,0 − c1,0 if n is odd.
Now, we must use the initial values T (0) = 1, T (1) = 1, and T (2) = 5 in order to find the
unknown values c1,0 , c2,1 , and c2,0 . Note that
Thus,
1 0 1 c1,0 1
−1 1 1 · c2,1 = 1 .
1 2 1 c2,0 5
211
We will use Gaussian Elimination to solve this system. First, we add the first equation from
the second, and subtract the first equation from the third, in order to obtain the system
1 0 1 c1,0 1
0 1 2 · c2,1 = 2 .
0 2 0 c2,0 4
We next subtract two times the second equation from the third in order to obtain the following
(equivalent) triangular system:
1 0 1 c1,0 1
0 1 2 ·
2,1 2 .
c =
0 0 −4 c2,0 0
Now we use “back substitution” to solve this system. The third equation is “−4c2,0 = 0,”
which implies that c2,0 = 0. The second equation is “c2,1 + 2c2,0 = 2,” which now implies that
c2,1 = 2 − 2 · 0 = 2. Finally, the first equation is “c1,0 + 0 · c2,1 + c2,0 = 1,” which implies that
c1,0 = 1 − 0 · 2 − 0 = 1. Thus,
(
2n + 1 if n is even,
T (n) = 1 · (−1) + 2n + 0 =
n
2n − 1 if n is odd.
If we made no arithmetic errors along the way, then this solution is correct. Of course, you
could use mathematical induction (yet again) to confirm that the function T (n) that was given in
the original problem really is equal to the one given here, as a check for any such mistakes.
for n ≥ 2. Use “the substitution method” to prove that T (n) ∈ O(n(log2 n)2 ) whenever
n = 2k is a power of two.
Solution: We will use mathematical induction (on k = log2 n) to show that T (n) ≤
cn(log2 n)2 for every power n of two, for some constant c.
Basis: If k = 0 then n = 1. Since T (1) = 0 and c·1·(log2 1)2 = c·1·0 = 0, T (1) ≤ c·1·(log2 1)2
for all c.
Inductive Step: Suppose now that k > 0, n = 2k , and that T (m) ≤ cm(log2 m)2 for m = 2h ,
212
for every integer h such that 0 ≤ h < k. Now
Now if we choose c = 1 (or, indeed, if we choose c to be any constant that is greater than or
equal to 1) then c satisfies all the constraints that were identified in the inductive proof.
Therefore, T (n) ≤ cn(log2 n)2 for any constant c ≥ 1 and for every power n of two, so
T (n) ∈ O(n(log2 n)2 ), as desired.
2. (10 marks) Now use “the iteration method” to find an expression in closed form that is an
exact solution for the recurrence given in Question 1. Once again, you may assume n = 2k is
a power of two.
X
k µ ¶ X
k X
k
n j
Hint: If n = 2k and k is a nonnegative integer then log2 = log2 (2 ) = j.
i=0
2i j=0 j=0
Note: A small number of bonus marks will be awarded if you also use mathematical induction
to prove that your solution is correct.
T (n) = n log2 n + 2T ( n2 )
= n log2 n + 2[( n2 ) log2 ( n2 ) + 2T ( n4 )]
= n log2 n + n log2 ( n2 ) + 4T ( n4 )
= n log2 n + n log2 ( n2 ) + 4[ n4 log2 ( n4 ) + 2T ( n8 )]
= n log2 n + n log2 ( n2 ) + n log2 ( n4 ) + 8T ( n8 ).
It is possible that a pattern is clear at this point; otherwise, one could continue to expand
and collect terms a few more times, until it seemed clearer that
213
for 0 ≤ i < k = log2 n. In particular, when i = k − 1,
X
k−1
T (n) = n log2 ( 2nj ) + 2k T ( 2nk )
j=0
X
k−1
= n log2 ( 2nj ) + nT (1)
j=0
X
k
= n log2 ( 2nj ) (since T (1) = 0 = log2 1)
j=0
à k ! à k !
X X
i
=n log2 (2 ) =n i (using the hint)
i=0 i=0
µ ¶
k(k + 1)
=n
2
= 12 nk 2 + 12 nk = 12 n(log2 n)2 + 12 n log2 n.
Thus (one might guess that) T (n) = 12 n(log2 n)2 + 12 n log2 n whenever n is a power of two.
Additional Material, for Bonus Marks: Up to three bonus marks will be awarded for
a correct proof that the above closed form is correct — that is, for a proof that T (n) =
2 n(log2 n) + 2 n log2 n, whenever n ≥ 1 is a power of two.
1 2 1
Inductive Step: Suppose now that n ≥ 2 is a power of two, and that T (m) = 12 m(log2 m)2 +
2 m log2 m whenever m is a power of two and 1 ≤ m < n. Then
1
as desired.
Therefore, it follows by induction on n that T (n) = 12 n(log2 n)2 + 12 n log2 n whenever n ≥ 1
and n is a power of two.
Note: The only part of the derivation that really needs to be confirmed (by proof) is the
pattern given in equation (11.5). Thus, full bonus marks will also be given for a proof by
induction that equation (11.5) is correct for 0 ≤ i < k = log2 n.
214
Solution for Sample Test in Section 8.12.2
1. Suppose a recursive algorithm for multiplication of two n-digit integers
• uses exactly c1 steps, for some positive constant c1 , if n < 3, and
• solves the problem when n ≥ 3 by
(a) multiplying together five pairs of smaller integers, using the same algorithm recur-
sively, where the smaller “input” integers are always exactly b n3 c digits long, and
(b) doing extra work that requires exactly c2 n steps for some positive constant c2 .
(a) (4 marks) Write down a recurrence for the number of steps used by the above multipli-
cation algorithm (as a function of n) in the worst case.
Solution: It follows from the description of the problem that the number of steps used
when the inputs are n-digit integers is
(
c1 if n < 3
T (n) =
5T (b n3 c) + c2 n if n ≥ 3.
(b) (3 marks) Find a function f (n) in closed form such that this algorithm uses Θ(f (n)) steps
to multiply two n-digit integers together.
Solution: This has the form needed for the simplified master theorem (Theorem 8.4
on page 132) to be applicable. It corresponds to the choice of constants a = 5, b = 3,
α = 1, and β = 0.
Now, since α = 1 < log3 5 = logb a, the first case described in this theorem is applicable,
so T (n) ∈ Θ(nlogb a ) = Θ(nlog3 5 ). Thus we can set f (n) = nlog3 5 .
2. (5 marks) Write a recursive function that takes a pointer to the root of a binary tree as input,
and returns the sum of the values stored at the nodes of the tree.
Use the following notation: if p is a pointer to a node, then
• ∗p.left is a pointer to the left child (and is “null” if the node does not have a left child);
• ∗p.right is a pointer to the right child (and is “null” if the node does not have a right
child);
• ∗p.value is the value stored at the node.
Solution: A recursive function sum of nodes, which takes a pointer to the root of the binary
tree as input and has the sum as its value (that is, the value returned), is as follows.
if (p = null) then
return 0
else
return (∗p.value + sum of nodes(∗p.left) + sum of nodes(∗p.right))
end if
215
3. Consider two “integer division” algorithms (that compute the quotient and remainder ob-
tained by dividing one n-digit input integer by a second n-digit input integer):
• Algorithm A uses T (n) steps, when given n-digit integers as input, where
(
c1 if n < 4,
T (n) =
7T (d n4 e) + c2 n + c3 if n ≥ 4,
and where c1 , c2 , and c3 are positive constants;
• Algorithm B uses Θ(n(log n)2 ) steps when given n-digit integers as input.
(a) (6 marks) Find a function f (n) in closed form such that T (n) ∈ Θ(f (n)) (where T (n) is
the number of steps used by Algorithm A, as above).
Solution: Once again, the simplified master theorem is applicable — this time, with
a = 7, b = 4, α = 1, and β = 0. Since α = 1 < log4 7 = logb a, the first case mentioned
in the theorem is applicable, so that T (n) ∈ Θ(nlogb a ) = Θ(nlog4 7 ). Thus we can set
f (n) = nlog4 7 .
(b) (2 marks) Say which of the above two algorithms is asymptotically faster — that is, say
which algorithm uses a smaller number of steps, when given n-digit integers as inputs,
for all sufficiently large n.
Solution: Since (log n)2 ∈ o(nc ) for any constant c > 0, (log n)2 ∈ o(n(log4 7)−1 ), and
n(log n)2 ∈ o(nlog4 7 ). Thus, algorithm B is asymptotically faster than algorithm A.
Be specific in your answer for the last part: It isn’t enough just to say that it does, or
does not, satisfy the definition you gave above.
Answer: No, this is not a recurrence, because its description of T (n) (for the case
n ≥ 1) refers to the value T (n + 1) of the function at a larger value, n + 1, as well as
smaller values.
216
(a) (8 marks) Use the substitution method — not the master theorem — to prove that
T (n) ∈ O(n4 )
assuming that n is a power of three (so that n = 3h for some integer h ≥ 0).
Solution:
Claim: There exists a constant c > 0 such that T (n) ≤ cn4 whenever n ≥ 1 and n is a
power of three.
Proof of Claim: By induction on h = log3 n.
Basis (h = 0): If h = 0 then n = 3h = 1, so that T (n) = T (1) = 0 and cn4 = c. It
follows that T (n) ≤ cn4 in this case, for any constant c such that c > 0.
Inductive Step: Suppose now that h ≥ 0 and that T (n) ≤ cn4 for n = 3h . It is necessary
and sufficient to prove, using only this assumption, that T (n̂) ≤ cn̂4 as well, for n̂ = 3h+1 .
Since h ≥ 0, n̂ = 3n ≥ 3, so
³ ´
T (n̂) = 9T b n̂3 c + n̂4 by the definition of T , since n̂ > 1
= 9T (n) + n̂4 since n̂ = 3n
≤ 9cn + n̂
4 4
by the inductive hypothesis (stated above)
¡c ¢ 4
= 9 + 1 n̂ since n̂ = 3n, so that n̂4 = 81n4
≤ cn̂4 provided that c
9 + 1 ≤ c, that is, c ≥ 9
8
T (n) ∈ Ω(n4 )
217
3. Consider, once again, the recurrence used in Question #2 and the function T (n) that it
defines.
(a) (5 marks) If you used the “iteration method” then you might make the following con-
jecture.
Claim: If k ≥ 0 and n is any power of three such that n ≥ 3k , then
³ ´ X³
k−1 ´i
T (n) = 9k T n
3k
+ n4 1
9 .
i=0
as required.
Inductive Step: Suppose, now, that k ≥ 0 and that
³ ´ X³
k−1 ´i
T (n) = 9k T n
3k
+ n4 1
9
i=0
for every power n of three such that n ≥ 3k . It is necessary and sufficient to prove, using
only the above assumption, that
³ ´ (k+1)−1 ³
X ´i
T (n) = 9k+1 T 3k+1
n
+ n4 1
9
i=0
218
(b) (3 marks) Now, use the claim to find an exact closed form for T (n) when n is a power
of three.
Solution: Since we wish to eliminate references³ to
´ the function T on the right hand
n
side, we should choose k so that the value of T 3k is given explicitly in the recurrence
for T ; that is, we should choose k so that
n
3k
= 1.
³ ´ X³
k−1 ´i
T (n) = 9k T n
3k
+ n4 1
9
i=0
³ ´ (log3 n)−1 ³
X ´i
log3 n n 4 1
=9 T 3log3 n
+n 9
i=0
³ ´log3 n
1 −
1
9
= n2 T (1) + n4
1− 1
9
à !
1 − n12
=n ·0+n
2 4
1 − 19
= 98 n4 − 98 n2 .
4. (4 marks) Perform a “change of variable” to write a recurrence for the function U (h) = T (n),
where h = log3 n (and n is a power of three, so that h is an integer), and T is as defined in
Question #2. For your convenience, here is the recurrence for T once again:
(
0 if n = 1,
T (n) = ¡ ¢
9T b n3 c + n4 if n > 1,
Solution:
219
Solution for Sample Test in Section 8.12.4
Several definitions and facts were given in the test and are used in the following sections; please
refer to Section 8.12.4 for this material.
1. (10 marks) Write pseudocode for a recursive procedure buildHeap which takes a pointer to
an “almost heap” as input and turns this “almost heap” into a heap.
Your procedure should work from “the bottom up” in the sense that it should recursively
turn the left and right subtrees of the root into heaps before it does anything else (unless, of
course, the input heap has size zero).
Your procedure can, and should, use the procedure setRoot as a subroutine.
If p is a pointer to a node, please use p.left and p.right to refer to pointers to the left and
right children of that node, respectively.
Solution:
procedure buildHeap(p)
buildHeap(p.left)
buildHeap(p.right)
setRoot(p)
end procedure
2. (5 marks) Write a recurrence for the running time T (n) used by your procedure when it is
given a pointer to an “almost heap” of size n as input. You should use the unit cost criterion
and you should assume that n = 2k − 1 for an integer k (that is, your recurrence only needs
to be correct for integers n with this form).
The following additional facts will be useful (and “almost true,”) and you may use them
without proving them:
• If k > 1 and n = 2k − 1 then the left and right subtrees of the root (of an “almost heap”
of size n) are both “almost heaps” with size 2k−1 − 1 = b n2 c.
• When you call setRoot with a pointer to an “almost heap” of size m as input for m ≥ 1,
it uses exactly c1 dlog2 me + c0 steps before it terminates, for some positive constants c1
and c0 (and, it uses c0 steps if m = 0).
Solution:
(
c2 if n < 3
T (n) = ¡ ¢
2T b n2 c + c1 dlog2 ne + c0 if n ≥ 3
in the special case that n = 2k − 1 for an integer k, and for a positive constant c2 and the
constants c0 and c1 mentioned in the above “facts.”
It should be clear that T (n) is less than or equal to the recursive expression on the right hand
side, above. It’s less obvious, but also true, that T (n) is equal to an expression in this form,
because the left and right subheaps can be “arbitrary” (or “any”) subheaps of the given size.
220
3. (5 marks) Use the master theorem to prove that T (n) ∈ Θ(n) if T (n) satisfies the recurrence
you gave to answer the previous question.
Solution: The above recurrence has the form that is considered in the master theorem and
corresponds to the choice of constants a = c2 , b = 2, c = 2, and the function f (n) =
dlog2 ne + c0 . Furthermore, the simplified version of the master theorem can be used, because
f (n) ∈ Θ(nα (log2 n)β ) where α = 0 and β = 1.
In this case logb a = log2 2 = 1 > α, so the first case covered by the (simplified) version of the
master theorem applies. Therefore
4. (5 marks) Finally, use the result you were supposed to prove in the previous question (whether
you managed to prove it or not!), and the assumption that the running time used by your
procedure is a nondecreasing function of n, to prove that this running time is linear in n in
general, and not just in the special case that n = 2k − 1 for some integer k.
Solution: It follows from the above result that there is some constant N , and positive con-
stants d0 and d1 , such that if n = 2k − 1 for any integer k, and n ≥ N , then d0 n ≤ n ≤ d1 n.
Now let N̂ be the smallest integer such that N̂ = 2k − 1 for some integer k and N̂ ≥ N .
Suppose n is an integer such that n ≥ N̂ . Then there exist integers ĥ and k̂ such that
ĥ = 2k̂ − 1 and N̂ ≤ n̂ ≤ n < 2n̂.
Since n̂ ≥ N̂ and 2n̂ ≥ N̂ , T (n̂) ≥ d0 n̂ and T (2n̂) ≤ d1 (2n̂). Furthermore it is given that T
is a nondecreasing function.
Therefore,
T (n) ≥ T (n̂)
≥ d0 n̂
≥ d0
2 n
= dˆ0 n where dˆ0 = d0
2 is a positive constant,
and
T (n) ≤ T (2n̂)
≤ d1 (2n̂)
≤ 2d1 n
= dˆ1 n where dˆ1 = 2d1 is a positive constant.
Therefore dˆ0 n ≤ T (n) ≤ dˆ1 n for every integer n ≥ N̂ , so T (n) ∈ Θ(n), as desired.
221
11.4 Midterm Tests
11.4.1 Solution for Sample Test in Section 9.1
1. (5 marks — 1 mark for each part) Say whether each of the following claims about functions
of n is true or false. You do not need to prove your answers.
³ ´n
(i) 3
2 ∈ Θ(2n ) Answer: false
(iii) 1
1000 n
1/10 ∈ O((log2 n)100 ) Answer: false
(iv) 1
1000 n
1/10 ∈ O(n100 ) Answer: true
√
(v) n2 + 2n ∈ Θ(2n2 + n) Answer: true
2. (10 marks) Let f (n) = en and let g(n) = n for n ≥ 0. Prove that f (n) ∈ ω(g(n)).
Solution: Since f 0 (n) = en , g 0 (n) = 1, and lim f (n) = lim g(n) = +∞,
n→+∞ n→+∞
f (n) f 0 (n)
lim = lim 0 (by l’Hôpital’s rule)
n→+∞ g(n) n→+∞ g (n)
en
= lim
n→+∞ 1
= +∞. (since e > 1)
X
n X
n
3. (10 marks) Let Sn = 13i5.5 = 13i11/2 .
i=1 i=1
Find a function f (n) in closed form such that |f (n) − Sn | ∈ O(n6 ), and prove that this
inequality holds for your choice of the function f .
Generous part marks will be given if you only find a function f (n) in closed form such
that Sn ∈ Θ(f (n)) (and prove that this relationship holds), instead.
(a) If g(x) = 13x5.5 , then g(x) is an increasing function of x (over the positive real numbers).
(b) If r > 1 then ((n + 1)r − nr ) ∈ O(nr−1 ).
222
Solution, for Full Marks:
X
n
Let g(x) = 13x11/2 , so that Sn = g(i), and let f (x) = 2x6.5 = 2x13/2 . Then f 0 (x) = g(x),
i=1
and it is given that g(x) is an increasing function of x (over the positive real numbers), so
that Sn can be approximated by integrals:
Z n X
n Z n+1
g(t) dt ≤ Sn = g(i) ≤ g(t) dt.
0 i=1 1
Since f 0 (x) = g(x), the lower bound given in the above equation is
Z n
g(t) dt = f (n) − f (0) = 2n13/2 − 2 · 013/2 = 2n13/2 ,
0
Now,
|f (n) − Sn | = Sn − f (n)
≤ (f (n + 1) − f (1)) − f (n)
= 2(n + 1)13/2 − 2 − 2n13/2
< 2((n + 1)13/2 − n13/2 )
∈ O(n11/2 ) (since it is given that (n + 1)13/2 − n13/2 ∈ O(n11/2 ))
⊆ O(n6 ) (since 11/2 ≤ 6.)
Thus, if f (n) = 2n13/2 , then f (n) satisfies all the conditions given in the question.
X
n X
n
Sn = g(i) ≤ g(n) = ng(n) = 13n13/2 .
i=1 i=1
This implies that S(n) ∈ O(n13/2 ). In order to show that S(n) ∈ Ω(n13/2 ), as well, note that
bn/2c
X X
n
Sn = SL + SU , for SL = g(i), and SU = g(i).
i=1 bn/2c+1
223
Let mL = min g(i). Then mL = g(1) = 13, and (since n > 0 and mL > 0)
1≤i≤bn/2c
bn/2c
X
SL = g(i)
i=1
bn/2c
X
≥ mL
i=1
¹ º
n
= · mL
2
¹ º
n
= · 13
2
µ ¶
n 13
≥ 13 − 1 = n − 13.
2 2
X
n
SU = g(i)
i=bn/2c+1
Xn
≥ mU
i=bn/2c+1
µ ¹ º¶
n
= n− mU
2
» ¼
n
= mU
2
µ ¶ µ ¶11/2
n n
≥ · 13 ·
2 2
13
·n 13/2
.
213/2
Therefore,
13 13
Sn = SL + SU ≥ n − 13 + 13/2 · n13/2 ∈ Ω(n13/2 ).
2 2
Since Sn ∈ O(n13/2 ) and Sn ∈ Ω(n13/2 ), Sn ∈ Θ(n13/2 ) (and we can set f (n) = n13/2 in order
to earn “generous part marks” for this question).
4. (5 marks) Find a function f (n) in closed form such that T (n) ∈ Θ(f (n)), where
(
1 if n = 1,
T (n) =
16T (dn/2e) + n3 if n ≥ 2,
224
Solution: This recurrence has the form
(
c0 if n < a,
T (n) =
aT (dn/be) + g(n) if n ≥ a,
where c0 , a, and b are positive constants and where g(n) is a function of n in closed form
(in particular, where c0 = 1, a = 16, b = 2, and g(n) = n3 ). Thus, it is possible that “the
master theorem” can be used to find an asymptotic approximation for T (n). Furthermore,
since g(n) ∈ Θ(nα (log n)β ) for α = 3 and β = 0, the “simplified master theorem” can be
used.
Since α = 3 < 4 = log2 16 = logb a, the first cased described in this theorem is applicable,
and this implies that T (n) ∈ Θ(nlogb a ) = Θ(n4 ).
Thus, the master theorem implies that if f (n) = n4 then T (n) ∈ Θ(f (n)).
Comments on Alternative Solutions: “In principle,” you could use other methods from
CPSC 413 to solve this problem, but this would not be nearly as easy to do as it was to apply
the master theorem:
It is possible to use “the iteration method” to establish that T (n) = 2n4 − n3 , whenever n is
a power of two. However, it would be necessary to prove, somehow, that T (n) ∈ Θ(n4 ) for
all other positive integers n as well, before you could correctly conclude that “T (n) ∈ Θ(n4 )”
(and consider this to have been proved). In particular, if you concluded that T (n) ∈ Θ(n4 )
after having obtained the closed form for powers of two (and without doing anything else),
then your answer was incomplete.
It should be noted as well that it is necessary to “guess a pattern” when using the iteration
method, in order to express the recurrence as a summation. In order to give a complete
“proof” of correctness of the resulting closed form — even just for powers of two — either the
“pattern” you guessed, or the closed form you obtained from it, must be verified (probably,
using induction on k = log2 n).
Now, suppose that you got as far as obtaining a closed form for T (n) when n is a power of
two (and proving that this is correct).
One way to complete a proof that T (n) ∈ Θ(n4 ) is to show (by induction) that T (n) is an
increasing function — that is, if m and n are integers and 1 ≤ m ≤ n, then T (m) ≤ T (n).
This proof by induction would not be very difficult (but, the special case n = 2 would need
to be treated carefully). At that point, you could note that if n ≥ 2 and k = blog2 nc, then
n/2 < 2k ≤ n < 2k+1 ≤ 2n, 2k and 2k+1 are powers of two, and
225
to prove that T (n) ∈ αn4 for some unknown value α would fail, because it would impossible
to prove the “inductive step” required. A second attempt, to prove that T (n) ≤ αn4 −βn3 for
all n ≥ 1, would also fail, because you would not be able to find constants α and β satisfying
all the constraints obtained during the attempt.
Now, note that it would be good enough to confirm that T (n) ≤ αn4 − βn3 “for all n ≥ n0 ,”
for some positive constant n0 . In order to prove this, you could try to choose a suitable
integer n0 , and then
(a) confirm that the inequality is satisfied for the “special cases” n = n0 , n0 + 1, n0 +
2, . . . , 2n0 − 2 (in the “basis” part of your proof); and, then,
(b) try to prove that the inequality is also satisfied for n ≥ 2n0 − 1 in the “inductive step.”
You would end up using the recursive definition for T (n) in the inductive step; now, provided
that the above values were all checked in the “basis,” you could safely assume that T (dn/2e) ≤
α(dn/2e)4 − β(dn/2e)3 in the inductive step when you needed to.
If you pick n0 to be too large, then there will so many special cases that need to be checked
in the basis that you would not have time to finish. However, if you pick n0 to be too small,
then you will discover that the constraints you’ve identified for α and β can’t all be satisfied.
At this point, I have not completed a proof along these lines. However, I suspect that this can
be made to work if you choose n0 = 5, and that it won’t work if n0 is chosen to be smaller
than that.
In any case, this would take much more time than you could afford to spend on a single
midterm question, and it was expected that you would apply the master theorem, and write
down the solution (almost) immediately after that, instead.
5. (10 marks) Find a closed form for the function T (n), where
0 if n = 0,
T (n) = 1 if n = 1,
2T (n − 1) − T (n − 2) if n ≥ 2,
and prove that your answer is correct. You may prove that your answer is correct either by
applying one of the theorems stated in class or by using mathematical induction.
There are at least three different ways to solve this problem, using techniques introduced in
CPSC 413. Of these three, the third is most likely the one to be attempted by students who
worked on Problem Set #5, and is the most reliable, in the sense that it is the only one that
does not require you to guess a pattern after examining a finite number of cases (and then
use induction to prove that your guess is correct).
Solution #1: In this solution, we will compute T (0), T (1), T (2), T (3), and so on, until
a pattern becomes clear. We will then guess a solution and then try to use mathematical
induction in order to prove that it is correct.
226
Now,
T (0) = 0,
T (1) = 1,
T (2) = 2T (1) − T (0) = 2 · 1 − 0 = 2,
T (3) = 2T (2) − T (1) = 2 · 2 − 1 = 3,
T (4) = 2T (3) − T (2) = 2 · 3 − 2 = 4,
and it would seem to be reasonable to conjecture at this point that T (n) = n for every integer
n ≥ 0. In fact, this is correct, as will be shown below by induction on n:
Inductive Step: Now suppose that n ≥ 2 and that T (m) = m for every integer m such that
0 ≤ m ≤ n − 1. Then
Solution #2: In this solution, we will try to use “the iteration method.” While we won’t
end up expressing the recursively defined function T (n) as a summation, we will find a way to
express T (n) in terms of T (1) and T (0), and this will allow us to find a closed form for T (n):
For large n,
T (n) = 2T (n − 1) − T (n − 2)
= 2(2T (n − 2) − T (n − 3)) − T (n − 2)
= 3T (n − 2) − 2T (n − 3)
= 3(2T (n − 3) − T (n − 4)) − 2T (n − 3)
= 4T (n − 3) − 3T (n − 4)
= 4(2T (n − 4) − T (n − 5)) − 3T (n − 4)
= 5T (n − 4) − 4T (n − 5).
At this point, it might seem reasonable to conjecture that “for every integer i such that
1 ≤ i ≤ n − 1,
227
On the other hand, if i = 1 and i is not between 1 and n − 1 then the claim is also true (since
“false implies anything”). Thus, the result is correct if i = 1.
Inductive Step: Suppose now that i ≥ 2 and that, for every integer j such that 1 ≤ j ≤ i−1,
the claim holds — that is, “if 1 ≤ j ≤ n − 1 then
Now, the claim is trivially true if i is not less than or equal to n − 1 (again, since “false implies
anything,”), so we may assume that 2 ≤ i ≤ n − 1. In this case, 1 ≤ i − 1 ≤ n − 2 < n − 1, so
Since T (n) = n when n = 0 and when n = 1 as well, it follows that T (n) = n for every integer
n ≥ 0.
Solution #3: Now, note that the given recurrence is a “linear recurrence with constant
coefficients.” The characteristic polynomial of this recurrence is
x2 − 2x + 1 = (x − 1)2 ,
for unknowns c1 and c0 . This equation holds when n = 0 and when n = 1, so that
0 · c1 + c0 = T (0) = 0,
and
1 · c1 + c0 = T (1) = 1.
The first of these equations implies that c0 = 0, and the second equation then implies that
c1 = 1. Therefore,
228
11.4.2 Solution for Sample Test in Section 9.2
1. (5 marks — 1 mark for each part) Say whether each of the following claims about functions
of n is true or false. You do not need to prove your answers.
(ii) 1
1000 (log n)
10 ∈ O(n1/100 ) Answer: True
√
(iv) n3 + 2n2 ∈ Θ(2n3 + n) Answer: True
Comment: Parts (a) and (b), above, could have been answered by recalling and applying
the “rule of thumb” that any fixed power of a logarithm grows asymptotically strictly more
slowly than any fixed power of n, provided that the exponent in the power of n is strictly
greater than zero. Similarly, part (e) could be answered using the rule of thumb that nc1
grows asymptotically strictly more slowly than nc2 whenever c1 and c2 are constants and
c1 < c2 . The remaining parts could be decided and answered by using limit tests.
2. (8 marks) Let f (n) = 3n2 + ln n and let g(n) = n2 for n ≥ 1. Prove that f (n) ∈ Θ(g(n)).
Solution:
f (n) 3n2 + ln n
lim = lim
n→+∞ g(n) n→+∞ n2
6n + n1
= lim by l’Hôpital’s rule
n→+∞
Ã
2n !
1
6n n
= lim +
n→+∞ 2n 2n
µ ¶
1
= lim 3 + 2
n→+∞ 2n
= 3.
Since the above limit exists and is a positive constant, it follows that f (n) ∈ Θ(g(n)).
Comments: L’Hôpital’s rule was applied correctly in the above derivation because
f 0 (n) = 6n + n1 , and g 0 (n) = 2n. Alternate solutions (including the use of the definition of
“Θ(g(n))” instead of the limit test) would also be completely acceptable.
229
X
n
3. Suppose n ≥ 1, Sn = g(i), where the function g(x) = x
ln(2x) is a nondecreasing function
i=1
of x — you may use this fact without proving it in this question.
(a) (9 marks) Find a function f (n) in closed form such that Sn ∈ Θ(f (n)), and prove that
this holds without using approximation by integrals.
Solution: Since it is given that g(x) is a nondecreasing function,
X
n X
n
n2 n2
Sn = g(i) ≤ g(n) = ng(n) = ln(2n) ≤ ln n .
i=1 i=1
X
m X
m
b n2 c
SL = g(i) ≥ g(1) = mg(1) = ≥ 0,
i=1 i=1
ln 2
and
X
n
SU = g(i)
i=m+1
X
n
≥ g(m + 1) since the function g is nondecreasing
i=m+1
= (n − m)g(m + 1)
¡n¢
≥ g(m + 1) since n − m ≥ n
and g(m + 1) ≥ 0
¡ n2 ¢ 2
≥ 2 g(n/2) since g is nondecreasing, m + 1 ≥ n2 , and n
2 ≥0
¡ n ¢ ³ n/2 ´
= 2 ln n
n2
= 4 ln n
³ 2´
1 n
= 4 ln n .
230
Therefore
³ ´ ³ ´
n2 n2
Sn = SL + SU ≥ 0 + 1
4 ln n = 1
4 ln n ,
³ ´
n2
which implies that Sn ∈ Ω ln n (since 1
4 is a positive constant).
³ ´
n2 n2
Therefore Sn ∈ Θ ln n , so Sn ∈ Θ(f (n)) where f (n) = ln n .
Comments: The approximations used above (for example, using 0 as a lower bound
for SL ) were chosen to obtain a lower bound that was “as clearly” in Θ(f (n)) as possible
— namely, a constant multiple of f (n). You could have made different approximations
— for example, avoiding “approximations” whenever possible — and obtained slightly
different upper and lower bounds as a result. If this happened and you still gave a
correct argument that your bounds were tight (possibly mentioning or using the limit
test, to prove this in the end), then this will be perfectly acceptable (if done correctly).
It would also be acceptable to use a completely different technique — probably, guessing
the final answer and then using the “substitution method” (involving a pair of proofs by
induction, with unknown constants included in the proofs), if you were using a technique
that had been introduced in the course.
However, this might be more difficult to do correctly, since it requires that you “guess”
the final answer instead of having it derived as part of the answer, and since the required
proofs by induction might be longer and messier than the solution that’s given above.
(b) (3 marks) Now suppose G(n) is a function of n such that G0 (n) = g(n). Use approxima-
tion by integrals to give a lower bound for Sn (that is, a function that is always less
than or equal to Sn ). Your answer should be an expression that involves G(n).
Solution: Since g(x) is a nondecreasing function,
X
n Z n
g(i) ≥ g(t) dt.
i=1 0
It’s given that G0 (x) = g(x), and it follows by the fundamental theorem of calculus that
Z n
g(t) dt = G(n) − G(0).
0
Therefore
G(n) − G(0)
4. (5 marks) Find a function f (n) in closed form such that T (n) ∈ Θ(f (n)), where
(
1 if n < 4,
T (n) =
16T (dn/4e) + 2n2 if n ≥ 4,
231
Solution: The above recurrence has the form that is required if the master theorem is to
be used, and it corresponds to the choice of constants a = 16, b = 4, and c = 1, and to the
function f (x) = 2x2 .
Furthermore, f (x) = xα (log2 x)β for constants α = 2 and β = 0, so this function is in the
form that’s required if the “simplified” master theorem is to be used.
In this case, α = 2 and logb a = log4 16 = 2 (since 16 = 42 ), so α = logb a. Since β = 0, the
second case given in the theorem is applicable.
Therefore, T (n) ∈ Θ(nlogb a log2 n) = Θ(n2 log2 n).
Comment: It will also be perfectly acceptable if you used the (corrected) original master
theorem instead of the simplified theorem in order to solve this problem.
The correct use of other techniques, such as the iteration method or the substitution method,
would be acceptable too. However, they weren’t required and (as the number of marks for
the question should have suggested), time wasn’t really allowed for this.
Hint: You should consider both the cases n = 0 and n = 1 as special cases.
Claim. There exists a positive constant c > 0 such that T (n) ≤ c4n for every integer n ≥ 1.
Proof of Claim. This will be proved by induction on n. As suggested by the “hint,” it will
be convenient to treat the cases n = 0 and n = 1 as special cases, so both will be considered
in the “basis.”
Basis: If n = 0 then T (n) = T (0) = 1 and c4n = c40 = c, so T (n) ≤ c4n in this case
provided that c ≥ 1.
If n = 1, then T (n) = T (1) = 8 and c4n = c41 = 4c, so T (n) ≤ c4n in this case provided that
4c ≥ 8; that is, provided that c ≥ 2.
Inductive Step: Suppose now that n ≥ 0 and that T (n) ≤ c4n and that T (n + 1) ≤ c4n+1 .
Then
232
as desired (without requiring any additional conditions on c).
The above conditions on c can be satisfied as long as c is chosen to be any positive constant
that is greater than or equal to 2. In particular, if c = 2 then all these conditions are satisfied.
It therefore follows by induction on n that the claim is correct (and, furthermore, that we
can choose the constant c mentioned in the claim to be 2).
It clearly follows from the claim (and the definition of O(4n )) that T (n) ∈ O(4n ), as desired.
Comment: As for the other questions, other correct solutions that used different techniques
will be perfectly acceptable — but the substitution method was probably the one that was
easiest to use correctly in this case. The fact that you were given an asymptotic bound in
closed form should have been an indication that the substitution method was a good method
to try first.
The iteration method could be used, “in principle,” but you’d very likely need to discover an
7 · 4 − 7 · (−3) and
exact solution in closed form, in order to make this work. Since T (n) = 11 n 4 n
n
there’s nothing in the above question that might suggest that “(−3) ” should be involved at
all, this would probably be quite difficult to do. (And, as usual, part marks will be awarded
for reasonable attempts.)
233
234
Bibliography
[1] Alfred V. Aho, John E. Hopcroft, and Jeffrey D. Ullman. The Design and Analysis of Computer
Algorithms. Addison-Wesley, 1974.
[2] Gilles Brassard and Paul Bratley. Fundamentals of Algorithmics. Prentice Hall, 1996.
[3] Thomas H. Cormen, Charles E. Leiserson, and Ronald L Rivest. Introduction to Algorithms.
McGraw-Hill/MIT Press, 1990.
[4] Ronald L. Graham, Donald E. Knuth, and Oren Patashnik. Concrete Mathematics: A Foun-
dation for Computer Science. Addison-Wesley, second edition, 1994.
[6] Ellis Horowitz, Sartaj Sahni, and Sanguthevar Rajasekaran. Computer Algorithms/C++.
Computer Science Press, 1996.
[7] Donald E. Knuth. The Art of Computer Programming, Volume 1: Fundamental Algorithms.
Addison-Wesley, third edition, 1997.
[8] Donald E. Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms.
Addison-Wesley, third edition, 1997.
[9] Donald E. Knuth. The Art of Computer Programming, Volume 3: Sorting and Searching.
Addison-Wesley, second edition, 1998.
[10] Richard Neapolitan and Kumarss Naimipour. Foundations of Algorithms Using C++ Pseu-
docode. Jones and Bartlett, second edition, 1997.
[11] G. Polya. How to Solve It. Princeton University Press, second edition, 1957.
[13] Robert Sedgewick. Algorithms in C, Parts 1-4: Fundamentals, Data Structures, Sorting,
Searching. Addison-Wesley, 1998.
[14] Robert Sedgewick and Philippe Flajolet. An Introduction to the Analysis of Algorithms.
Addison-Wesley, 1996.
[15] Daniel Solow. How to Read and Do Proofs. Wiley, second edition, 1990.
235
Index
236
estimation by summation, 54 recurrence
evaluation using antiderivative, 54 change of function, 127
indefinite, 53 change of variable, 126
integration by parts, 56 definition, 112
integration by substitution, 55 iteration method, 120
iteration method, 120 restriction of domain, 125
simplification, 124
l’Hôpital’s Rule, 49 substitution method, 113
limit, 41 recurrences
cancellation of a common factor, 45 divide and conquer, 129
definition, 42 linear recurrence, closed form, 141
l’Hôpital’s Rule, 49 linear recurrences, 140
of a constant, 44 master theorem, 129
of a continuous function, 48 simplified master theorem, 132
of a difference, 44 Riemann Sum, 54
of a function of integers, 43 running time
of a product, 44 worst case, 64
of a quotient, 44
of a sum, 44 Simplified Master Theorem, 132
sandwiching the limit, 45 substitution method, 113
linear recurrence summation
characteristic polynomial, 140 applying linear operators, 93
closed form, 141 approximation by an integral, 98
definition, 140 arithmetic series, 87
logarithm bounding terms, 95
natural, 50 completing a pattern, 91
completing a pattern for approximation,
Master Theorem, 129 99
mathematical induction, 28 geometric series, 89
different starting point, 30 splitting the sum, 96
multiple cases in basis, 32 telescoping sum, 90
standard form, 28
strongest form, 33 telescoping sum
modification of recurrence, 124 definition, 90
237