i have a general question (taken from some computer science test) i'd like to get an explanation for, the question was:
Sorted array given a particular size, and suppose we use the fastest method in computer science to find values ββin the array. In this method, the search time of any element is no more than N seconds. Now we multiply the size of the array. The search time of any element in the array will be at most:
Answer: N+1.
Can anyone please give me a full explanation why this is the answer? and why isn't it 2*N ?
Thanks.
I think that the sentence "In this method, the search time of any element is no more than N seconds" is there just to confuse you.
I will ignore the seconds and consider it as O(N) steps.
There is an algorithm to find the element in log(x) steps (binary search - see the other answe). So
log2(x) = N
log2(2*x) = N+1
(I know this is not very precise and formal, but I hope you get the idea).
I suppose they mean binary search algorithm as fastest method for searching in sorted array. It is algorithm of type "divide and conquer", so for one step of such algorithm we reduce searching area by half.
Example:
Let's define one step in our algorithm take 1 unit of time
array = [1 2 3 4 5 6 7 8], to find = 7
We test our value as the last element in first array.
1 step: divide into [1 2 3 4] and [5 6 7 8], 4 < 7, our value in second array
2 step: divide into [5 6] and [7 8], 6 < 7, our value in second array
3 step: divide into [7] and [8], 7 = 7, we found it.
It is how binary search works and consumes 3 units of time.
Now imagine we doubled array to [1..16], we need 1 more step to reduce array to previous one, so we need 4 units of time.
Related
Today I had Interview where I was asked one problem, and I couldnt even understand.
Problem:
Given one array π consisting of π integers.
Get at least π equal elements in the array π.
While calculating, you can do below two operations
Take one of the minimum elements of the array and increase its value by one (more formally, if the minimum value of π is ππ then you choose such index π that ππ=ππ and set ππ:=ππ+1);
take one of the maximum elements of the array and decrease its value by one (more formally, if the maximum value of π is ππ₯ then you choose such index π that ππ=ππ₯ and set ππ:=ππβ1).
Calculate the minimum number of moves required to obtain at least π equal elements in the array.
Can anyone help me to undestand, what's a actual problem is about so that I could write code ?
To answer your question directly, which is "Help me understand the problem":
For example, here's your array:
{1,2,5,7,8,3}
Now, you can do only those two operations:
Find the minimum element and increase it:
{2,2,5,7,8,3} // <-- increased 1
Decrease the maximum element:
{2,2,5,7,7,3} // <-- decreased 8
And the question now is: What is the minimum number of moves to make this array contain k identical numbers?
So if k = 3 and the array is like the above, then one of the solutions would be to run operation 1 three times:
Before any moves:
{1,2,5,7,8,3}
After first move:
{2,2,5,7,8,3} // <-- `1` changed to `2`
After second move:
{3,2,5,7,8,3} // <-- `2` changed to `3`
After third move:
{3,3,5,7,8,3} // <-- `2` changed to `3`
So the resulting array would be:
{3,3,5,7,8,3}
Do you understand the problem now?
In terms of the algorithm to find k equal elements:
At any given step in the algorithm, there are some number of equal elements, say j. If j >= k, you're done. Otherwise, you need to choose some combination of the moves to increase j.
You don't have much flexibility in what you can do. You can only reduce a maximal element, or increase a minimal element.
Let's say there is a unique maximal element (i.e. when there is only one element in the array equal to the maximum element). You can increase j by (at least) 1 by reducing that until it equals the second-largest element.
Similarly, you can increase j by (at least) 1 by increasing a unique minimal element (i.e. when there is only one element in the array equal to the maximum element) until it equals the second-smallest element.
Therefore, the smallest number of moves to achieve the (at least) 1 increase is the one out of [decrease the maximal; increase the maximal] which achieve this.
For example, in the array [1, 3, 5, 6], your choices are:
Take 2 moves to increase the 1 so it equals 3: [3, 3, 5, 6]
Take 1 move to decrease the 6 so it equals 5: [1, 3, 5, 5]
In this case, you increase j by 2 most cheaply by decreasing the 6.
But after doing that, there are equal maximal elements: there are two elements equal to 5. By decreasing one of these, you decrease j by 2 (because [1, 3, 4, 5] has no equal elements); but by decreasing the maximum again, you make j the same as it was before (because [1, 3, 4, 4] again has 2 equal elements). So, you've got to do some work to "stand still" (that is, get j back to its previous value), before you can then decrease the maximum to increase j.
(Similarly for the minimal elements)
So, your algorithm can find the (greedy) minimum number of steps to make j == k by deciding whether to [decrease the maximal elements] or [increase the minimal element]. I don't know if the greedy minimum is actually the minimum, but I can't think of an obvious algorithm to find it non-greedily, other than searching all possibilities, which would have awful computational complexity, so is probably not what this interview was looking for.
Cracking The Coding Interview(5th ed): Chp 11, Ques 7
Question: A circus is designing a tower routine consisting of people standing atop one another's shoulders. For practical and aesthetic reasons, each person must be both shorter and lighter than the person below him or her. Given the height and weights of each person in the circus, write a method to compute the largest possible number of people in such a tower.
My doubt:
In the solution given in the book it is clearly mentioned in the text
that sorting the elements will make the solution too trivial then why
elements have been sorted initially in the code?
If the elements do not need to stay in the same(relative) order, then
we would simply sort the array. This makes the problem too trivial, so
let's assume that the elements need to stay in the same relative
order.
Here is the code from the book where sorting has been done(First three lines of the code):
ArrayList<HtWt> getIncreasingSequence(ArrayList<HtWt> items)
{
Collections.sort(items);
return longestIncreaingSequence(items);
}
The proposed solution is composed of 2 steps:
sort by weight
find the longest increasing subsequence on the heights
The quoted sentence is not relative to the first step, but to the second step (finding the longest increasing subsequence) and it is explaining that we can't just sort the heights because we can't change their order since they are already sorted by their weights.
Take a look at this example with 5 people:
weights: 4 5 1 7 2
heights: 6 3 5 4 1
Result after step 1 (sorting by weight):
weights: 1 2 4 5 7
heights: 5 1 6 3 4
Now, looking at the heights we can see that the longest increasing subsequence is 1 3 4 which tell us that the solution is composed of 3 people. To obtain that result we can't just sort by heights because since they are already sorted by their weight...
... the elements need to stay in the same relative order.
So we need to use a longest increasing subsequence algorithm instead.
If I am given a group of numbers that are positions on the y axis how do I find the position on the y axis that is has the shortest total difference in respect to the group of numbers. For example, if you are give the numbers 1 8 3 6 2 7 it should return the number 5 because it has the smallest total difference at 15. It has to be a divide and conquer approach. I do not need code I need an explanation.
Let's take your example: 1 8 3 6 2 7. I'm assuming we're looking for an integer answer.
The answer has to be between the smallest and the largest number. 0 has a larger sum of differences than 1. 8 has a smaller sum of differences than 9.
With your example, the end bounds are 1 and 8. Add them together and integer divide by 2. This gives us 4. Or, as an alternative, add all the numbers together and divide by the number count. With your example the sum is 27. Integer dividing by 6 yields 4.
The sum of the differences for 4 is 15. First, let's back up and see if the answer is smaller.
The sum of the differences for 3 is 15. So, let's back up again.
The sum of the differences for 2 is 17. We don't have to go any further in this direction. So, going the other direction from 4.
The sum of the differences for 5 is 15. So, let's move forward.
The sum of the differences for 6 is 15. Again, let's move forward.
The sum of the differences for 7 is 17.
So, the final answer is 3, 4, 5, or 6. I'm not sure how you choose one to be the correct answer.
In this case, we could have just checked all the numbers between 1 and 8, inclusive. But when the integers get to be larger, like 1,000, this divide and conquer method is faster.
Sort the numbers. You can use a divide and conquer algorithm for that.
Then the optimal line is at the number in the middle, or anywhere between the two middle numbers if there are an even number of them.
Notice that in your example, 3, 4, 5, and 6 all have a total difference of 15.
Why this works:
If you have n numbers above your line and m numbers below your line, and you move your line by 'x', then the change in the total difference is m*x - n*x. So if your line has more numbers above, then you should move it up. If it has more numbers below, then you should move it down. When it has the same number above and below, then it's optimal.
I came across an array sorting algorithm that seems pretty good, however it recurses using sub-arrays. I heard the time complexity of making a sub-array is O(n), which more or less stops any efficient sort from using sub-arrays.
The algorithm:
Take a pivot. We'll call it the last number in the array every time for the purpose of demonstration.
Put the pivot in its correct place. Here, you would look at 2 and 6, and if 6 is greater, put it after 2. Then look at 1 and 2, and if it's less, put it on the left. If two numbers are equal, I chose to put the pivot on the left.
Take the sub-arrays on both the left and right side of the pivot and recur on those.
Stop when the sub-array size is one.
A worked example:
6 1 7 8 6 9 1 2 Pivot would be 2
1 1 2 6 6 7 8 9 Put 2 in it's place, time to take sub-arrays
[1 1] 2 [6 7 8 9] Recur.
1 1 2 [6 7 8] 9 Recur more.
1 1 2 [6 7] 8 9 Recur.
1 1 2 6 7 8 9 Done!
What is the time complexity? Also, I'd be interested to see the time complexity if taking a subarray just takes O(1) time.
I think worst case this algorithm is O(n^2), but what is it average case?
Also please don't link a better sort, I'm trying to figure out a good sort on my own.
You have described the Quick Sort algorithm, which has average time complexity of O(n log n) and worst case time complexity of O(n^2) (oddly enough when the array is already sorted).
This is in java. Suppose that your Quick-Sort algorithm uses a pivot rule that picks the element in the βmiddleβ. That is, for an array A[0,1,...,nβ1] of size n, it uses the element in A[n/2] as pivot if n is even and the element in A[(n β 1)/2] as pivot if n is odd. Illustrate how this algorithm works using a quick-sort tree on the input:
[7 6 5 4 3 2 1]
Would the first pivot be 5 or 4? I was thinking it would be 5 since (7-1)/2 = 3 and 5 is the 3rd element, or would it be the 3rd index, which is the element 4?
size of your array is 7
the size is odd so [(n-1)/2] will be used -> [(n-1)/2] = [(7-1)/2] = 3
It will be 3rd index i.e. 4th element
which is in your case 4
[7 6 5 4 3 2 1] has 7 elements, so being odd you said it calculates the pivot using: A[(n-1)/2]
So, (7-1)/2 => 6/2 => 3rd position in the array, in your case number 4
Take into account that this kind of division will always return a truncated integer.
For example, 5/2 = 2, 3/2 = 1