Algorithm Big Omega - big-o

I am having trouble analyzing the following.
for b = 1 to n
for u = b to n
for i = b to u
Print
I am having trouble determining the worst-case runtime.
The first loop runs n times, the second loop runs (n(n+1))/2 times.
I then beleive that the third loop runs (n+1)/2 times.
However I have been told that it has a runtime of O(n^3).
Therefore it's best-case runtime can't be greater then the worst-case runtime!
I'm hoping for a push in the right direction if possible!
Thanks!

The third loop executes Print u-b+1 times {3} when it is activated.
When the second loop is activated, the third loop is activated for all u from b to n, i.e. executes Print 1+2+3+...n-b+1 times (substitute u=1, 2, 3...n in {3}). Using the formula for triangular numbers, this count equals (n-b+1)(n-b+2)/2 {2}.
When the first loop is activated, the second loop is activated for all b from 1 to n, i.e. executes Print n(n+1)/2 + (n-1)n/2 + (n-2)(n-1)/2 + ... 1 times (substitute b= 1, 2, 3... n in {2}; the counts are decreasing).
Using the formula for tetrahedral numbers, this equals n(n+1)(n+2)/6 {1}.
If you have trouble with this approach, you can simulate the Prints by hand instead.
For n=1
*
For n=2
*
* *
*
For n=3
*
* *
* * *
*
* *
*
For n=4
*
* *
* * *
* * * *
*
* *
* * *
*
* *
*
...
You clearly see the pattern of triangles of decreasing size. The area of the triangles grows as the square of the side. The total volume grows as the cube of the side.

Related

How do I write the formula correctly in my comments?

I want to write this formula in comments:
And this is how I wrote the formula in comments:
// based on formula S = n/2 * (a + (a*n))
However if I'm comparing the comments with the formula then it's missing the Sn, a1 and the an part.
My question is: how do I write the formula correctly in my comments?
You should use a multi-line comment in your the code before the function or the code. for example:
/*
* Formula to calculate sum of n numbers
* S = n/2 * (a + l)
* where S is the sum of n elements
* n is the number of elements
* a is the first element in the series
* l is the nth element in the series
*/

How to derive the main depth of binary tree is O(sqrt(N))?

In the Second Version of Data Structures and Algorithm Analysis in C,about the binary tree,there is the description that the mean depth of binary tree is O(sqrt(n)). I try to prove that,but I have no ideas about how to do that,Is there anyone who can help me?
Let us consider prefect binary tree (always splitting elements into 2):
*
* *
* * * *
* * * * * * * *
if I remove gaps and align to left:
*
**
****
********
You see that each depth level doubles the number of elements in it (in comparison to previous level) so:
n = 1 + 2 + 4 + 8 + ...
or:
n = sum( 2^i ) where i={ 0,1,2, ... ,level-1 }
So if you think of it (like binary number with all bits set) its the same as:
n = 2^level -1
so extracting level from it:
n = 2^level -1 // +1
n+1 = 2^level // log2
log2(n+1) = level
where n is number of elements and level is tree depth.
For different number of splits just the base of the logarithm changes... However for usual real trees the splits are not regular and you need to take into account average number of splits per element instead ...
If your tree's level should be proportional to O(sqrt(n)) then the elements should form a square (level^2 = n) or rectangle so speculating graphically:
******
******
******
******
******
******
######
*#####
**####
***###
****##
*****#
#
*##
**###
***####
****#####
*****######
*
***
*****
*******
*********
***********
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
* * * * * * * * * * *
so most of elements does not split just first and last in each level splits into 2 except the first level which splits to 3. If I chose a rectangle instead of square then the wider rectangle the more splits on average would be there ...
*
* *
* * *
* * * * *
* * * * * * *
* * * * * * * * *
* * * * * * * * *
That's the average depth of a binary tree, not a balanced one, by the way, where the maximum depth is proportion to logN. Paraphrasing the section that's relevant:
A property of a binary tree that is sometimes important is that the depth of an average binary tree is considerably smaller than N.
An analysis shows that the average depth is O(√N), and that for a special type of binary tree, namely the binary search tree, the
average value of the depth is O(logN). Unfortunately, the depth can be as large as n-1.
To work that out, you can generate all the possible trees for a certain value of N, then just average those depths.

Levenshtein Matrix using only a diagonal strip

According to wikipedia there's a possible modification to the Wagner-Fischer-algorithm that can calculate if the Levenshtein distance of two words is lower than a certain threshold, that is much quicker than the original one if that's all you want to know.
"By examining diagonals instead of rows, and by using lazy evaluation, we can find the Levenshtein distance in O(m (1 + d)) time (where d is the Levenshtein distance), which is much faster than the regular dynamic programming algorithm if the distance is small."
How does this solution work? I'm having a real hard time visualizing it since it feels like the value of any matrix cell depends on the values of the cells above, to the left and diagonally up to the left of it, so I'm not sure how to traverse the matrix using only a diagonal strip.
Second attempt at explanation:
Suppose that we're finding the distance between a length-m word and a length-n word. Let the matrix entries be indexed by [0, m] × [0, n], where the (i, j) entry represents the edit distance between the length-i prefix of the length-m word and the length-j prefix of the length-n word.
We can view the dynamic program as finding the shortest path from (0, 0) to (m, n) in a directed graph whose vertices correspond to matrix entries, with length-1 rightward arcs and length-1 downward arcs and length-0 or length-1 diagonal arcs depending on whether the characters at i and j match. The idea, in a nutshell, is to use A* with the length difference heuristic H(i, j) = |(m - i) - (n - j)|. Then, we don't expand nodes whose A* value is greater than d. The result is that only some of the diagonals need to be opened:
o t h e r w o r d
t * * *
h * * *
e * * *
w * * *
o * * *
r * * *
d * * *
First attempt at explanation:
Each matrix entry (i, j) is lowerbounded by |i - j|, because that's a lowerbound on the number of non-diagonal moves needed to reach that state. The strip is every element whose coordinates (i, j) satisfies |i - j| ≤ d, which looks like
o t h e r w o r d
t * * *
h * * * *
e * * * * *
w * * * * *
o * * * * *
r * * * * *
d * * * * *
for d = 2. When the values for the blank elements off of the strip are needed, just use d. At the end, any strip entry that's ≤ d is valid, because the blank elements can only contribute d + 1, seeing as the upper left neighbor of a strip element is also on the strip.
For words of different lengths, we can actually apply the argument to the transpose and restrict to the strip like
o t h e r w o r d
t * * *
h * * *
e * * *
w * * *
o * * *
r * * *
d * * *
though the asymptotic running time is the same.

Spoj - EverLast - Need Hint

I am trying to solve the SPOJ Problem EVERLAST, as given here,
The fate of the Pineapple
Currently what I am trying is:
1) After the first season the population = N * K
2) After the second season the population = N * K^2*(1-p)
since p is the probability that each pineapple is sterile and the initial N* K population dies out
3) After the third season the population = N * K^3 * (1-p)^2
a)The probability that pineapple population survives after second season = (1- p^(N * K)), since it dies out completely with a probability p^(N * K)
b)Probability that pineapple population survives after third season = 1 - p^ (N* K^2 *(1-p)), since it dies out completely with a probability p^(N * K^2 * (1-p))
and so on..
so the probability of population surviving forever will be
(1-p^(N * K)) * (1-p^(N * K^2 * (1-p))) * .......
But I am getting the wrong answer, I cant find the hints to this anywhere.
Where am I going wrong in my approach? any hints please?

Understanding How Many Times Nested Loops Will Run

I am trying to understand how many times the statement "x = x + 1" is executed in the code below, as a function of "n":
for (i=1; i<=n; i++)
for (j=1; j<=i; j++)
for (k=1; k<=j; k++)
x = x + 1 ;
If I am not wrong the first loop is executed n times, and the second one n(n+1)/2 times, but on the third loop I get lost. That is, I can count to see how many times it will be executed, but I can't seem to find the formula or explain it in mathematical terms.
Can you?
By the way this is not homework or anything. I just found on a book and thought it was an interesting concept to explore.
Consider the loop for (i=1; i <= n; i++). It's trivial to see that this loops n times. We can draw this as:
* * * * *
Now, when you have two nested loops like that, your inner loop will loop n(n+1)/2 times. Notice how this forms a triangle, and in fact, numbers of this form are known as triangular numbers.
* * * * *
* * * *
* * *
* *
*
So if we extend this by another dimension, it would form a tetrahedron. Since I can't do 3D here, imagine each of these layered on top of each other.
* * * * * * * * * * * * * * *
* * * * * * * * * *
* * * * * *
* * *
*
These are known as the tetrahedral numbers, which are produced by this formula:
n(n+1)(n+2)
-----------
6
You should be able to confirm that this is indeed the case with a small test program.
If we notice that 6 = 3!, it's not too hard to see how this pattern generalizes to higher dimensions:
n(n+1)(n+2)...(n+r-1)
---------------------
r!
Here, r is the number of nested loops.
The 3rd inner loop is the same as the 2nd inner loop, but your n is a formula instead.
So, if your outer loop is n times...
and your 2nd loop is n(n+1)/2 times...
your 3rd loop is....
(n(n+1)/2)((n(n+1)/2)+1)/2
It's rather brute force and could definitely be simplified, but it's just algorithmic recursion.
The mathematical formula is here.
It is O(n^3) complexity.
This number is equal to the number of triples {a,b,c} where a<=b<=c<=n.
Therefore it can be expressed as a Combination with repetitions.. In this case the total number of combinations with repetitions is: n(n+1)(n+2)/6
1 + (1+2) + (1+ 2+ 3 ) +......+ (1+2+3+...n)
You know how many times the second loop is executed so can replace the first two loops by a single one right? like
for(ij = 1; ij < (n*(n+1))/2; ij++)
for (k = 1; k <= ij; k++)
x = x + 1;
Applying the same formula you used for the first one where 'n' is this time n(n+1)/2 you'll have ((n(n+1)/2)*(n(n+1)/2+1))/2 - times the x = x+1 is executed.

Resources