Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Hi I am learning algorithms using python. I was going through some sample questions in the book where it asks to show why the worst case time of the extraction operation on a heap
implemented as an array is O(log n)? I have no clue where to start on this and I am getting close to the exam. Could anyone please help me prove this?
Thanks
Let's say we have a max heap. I will illustrate for n = 7, but logic is the same heaps of bigger size.
Worst case for extract happens when the root node has been changed to contain the smallest value of all the nodes (we extract the root in O(1) and put the last element in the array to be a root).
Now when we call Max-Heapify on the root, the value will have to be exchanged down with its child at every level, until it reaches the lowest level.
This is because, after every swapping, the value will still be smaller than both its children (since it is the minimum), until it reaches the lowest level where it has no more children.
In such a heap, the number of exchanges to max-heapify the root will be equal to the
height of the tree, which is log(n). So the worst case running time is O(log n).
Assuming a min priority queue:
Disregarding the actual extraction which is O(1), remember that when you extract the smallest value from a heap, you swap the last element with the first one then restore the heap property by comparing this element to it's children and swapping accordingly. Using heap property, the children of any node p are at index 2p and 2p + 1. So in the worst case, to find the children of any node, one would have to check nodes:
{ 2p, 2 * 2p, 2 * 2 * 2p, ..., N - 1 }
{ 2p, 4p, 8p, ..., lg2N(p) }
or
{ (2 1)p, (2 2)p, (2 3)p, ..., (2 lg2N)p }
So as you can see, the maximum number of elements to check in the worst case is lg2(N)
This was a pretty rough way of showing this property, I apologize
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Can you help me with problem? Given N <= 10^5 pairs of points, suppose they are written in
array A, A[i][0] <= A[i][1]. Also, given M <= 10^5 pairs of segments, i-th pair given in form L_1[i], R_1[i], L_2[i], R_2[i]. For each pair of segments I need to find number of pairs from array A, such that for each pair (A[z][0], A[z][1]) it should be L_1[i] <= A[z][0] <= R_1[i] <= L_2[i] <= A[z][1] <= R_2[i].
I think here we can use scan line algorithm, but I don't know how to fit in time and memory. My idea works in N * M * log(N).
If you map A[i] to a point (A[i][0], A[i][1]) on 2d-plane, then for each segment, basically you're just counting the number of points inside the rectangle whose left-bottom corner is (L_1[i], L_2[i]) and right-top corner is (R_1[i], R_2[i]). Counting the points on 2d-plane is a classic question which could be solved in O(n logn). Here are some possible implementations:
Notice that number of points in a rectangle P(l,b,r,t) could be interpreted as P(0,0,r,t)-P(0,0,l-1,t)-P(0,0,r,b-1)+P(0,0,l-1,b-1), so the problem can be simplified to calculating P(0,0,?,?). This could be done easily if we maintain a fenwick tree during the process which basically resembles scan line algorithm.
Build a persistent segment tree for each x-coordinate (in time O(n logn)) and calculate the answers for segments (in time O(m logn)).
Build a kd-tree and answer each query in O(sqrt(n)) time. This is not efficient but could be useful when you want to insert points and count points online.
Sorry for my poor English. Feel free to point out my typos and mistakes.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have an array of elements A1,A2,...,An.
The probability of a user searching for each element are P1,P2,...,Pn.
If the elements are rearranged, will the average case of the algorithm change?
Edit : I have posted the question, which appeared in my exam.
The expected number of comparisons is sum_{i=1...n}(i * p_i).
Re-ordering the elements in descending order reduces the expectation. That's intuitive since by looking at the most probable choices first will reduce, on average, the number of elements looked at before you find a particular choice.
As an example, suppose there's three items k1, k2, k3 with match probabilities 10%, 30% and 60%.
Then in the order k1, k2, k3, the expected number of comparisons is 1*0.1 + 2*0.3 + 3*0.6 = 2.5
With the most likely first: k3, k2, k1, the expected number of comparisons is 1*0.6 + 2*0.3 + 3*0.1 = 1.5
No, because it takes O(1) time to access an element in array and it does not depend on a position of this element in array. So arr[0] and arr[10000] should take the same amount of time.
If you will have something like a linked list or a binary tree, then it makes sense to put elements that are accessed with higher probability closer to the beginning.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
In terms of Big - O notation the linear search is a x^n, but what is the binary search? I am not 100% that the linear search is correct.
Linear search means that you will have to iterate through the list of elements until you find the element that you were looking for.
For instance, if you have a list with elements [1, 3, 5, 7, 9, 11] and you are looking for 11 you will start by the first element, then the second element, and so on, which in this case will take 6 iterations.
Generally, we could say that in the worst case you will have to traverse the whole list; so it will take n iterations, where n is the number of elements on the list.
So we say that the linear search algorithm is O(n).
In the case of binary search, you start on the middle element of the list:
Case 1: the number we are searching is the same as the number on the middle element: we are done!
Case 2: the number we are searching is smaller: we will only search the elements that precedes the middle element.
Case 3: the number we are searching is bigger: we will only search on the subsequent elements.
In our example, the number we are searching is 11 and the middle element is 5; since 11 > 5, we will only search on the sublist of the elements bigger than 5, namely [7, 9, 11].
Now, we will keep doing the same until we find the element that we are searching, in this case it takes only three iterations to get to the last element.
In general this approach takes log(n) iterations; therefore, the algorithm is O(log(n)).
Note that the latter only works for sorted lists.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am given an empty stack , I need to support three operations :
PUSH x : Push element x onto the stack
POP : Pop the top element
INC L R x : Increment the L to R elements by x
After each query I need to tell the top element of array. How to do this question if their can be 10^6 queries.
We can't update all the elements again and again. So please provide an efficient solution.
We can use a segment tree that supports your required operations in O(log n):
Increment all elements in a given range
For each node in your segment tree associated with an interval included in your given range, increment a counter num_increments for it: this counter will tell you how many times the elements in this range were all incremented. Only do this for the topmost such nodes, do not recursively go down to their children once you've done this.
Query the value at a given index
The answer to this is v[index] + number_of_increments. You can find the number of increments by finding the node associated with the index in the segment tree and keeping track of its parents' num_increments values as you walk down to it.
There are a couple of things to consider, depending on your exact problem:
For a given L, R, maybe set R = min(R, stack.Size), as it makes no sense to increment elements not yet in the stack. Or maybe it does for your problem, I don't know. If it does make sense for your problem, it makes things easier, and it invalidates my second point below;
What happens when you pop an element from the stack? This method will still mark its position as incremented, so if you push one back, it will consider it incremented by 1. Think about how you can also support decrement for a given index (it's similar to the query operation).
Incrementation by x instead of 1 should be easy to achieve.
There will be more push than pop operations, otherwise the stack would be empty in the end. Look for the last push that doesn't have a corresponding pop, this is the element that will be on top of the stack in the end. Now simply increment this element for each appropriate inc operation.
Complexity for this method:
O(2n) computation
O(queries) memory
n = total number of operations of all queries
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to propose an algorithm for the following: let us assume that we have an array consisting of zeros and ones. The array is filled with zeros from the beginning of the array to the index m, and all remaining indexes are filled with ones. I need to find this index m in O(logm) time. Here is what i thought: I think this is like binary search, first i look at the middle element of the array, if that is zero, then i forget about the left part of the array and do the same for the right part, and continue like this until i encounter a one. If the middle element is one, then i forget about the right part and do the same for left part of the array. Is this a correct O(logm) solution? Thanks
It is not "like" a binary search - it is a binary search. Unfortunately, it is O(logN), not O(logM).
To find the borderline in O(logM), start from the other end: try positions {1, 2, 4, 8, 16, ... 2^i} and so on, until you hit a 1. Then do a binary search on the interval between 2^i and 2^(i+1), where 2^i+1 is the first position where you discovered a 1.
Finding the first 1 takes O(logM), because the index is doubled on each iteration. After that, the binary search takes another O(logM), because the length of the interval 2^i..2^(i+1) is less than M as well.