I've been working on the exercise and stumbled upon a problem.
Given an array of integers, determine whether or not it can be partitioned into two arrays, each of which is in increasing order. For instance 3,1,5,2,4 can, but 4,8,1,5,3 can't.
The problem is here. I couldn't understand why 1st array can but the 2nd one can't.
There is a hint given:
If we successfully partitioned an initial segment of the array, one of the parts must contain the maximum element seen so far. It is obviously in our best interest that the largest element of the other part be as small as possible. So, given the next element, if it's the maximum to this point add it to the "maximum containing part". If not there is no choice but to add it to the other part if possible (e.g: if it is larger than the largest element of this part, but it is not the current maximum). If this procedure fails then no partition is possible, and if it succeeds then we have demonstrated a partition.
The most important part is to understand the logic of this partitioning.
Thank you in advance.
Let's use the given algorithm on {3,1,5,2,4}.
First number is 3. Our partition is {3},{}.
Next comes 1. We can't add that to {3}, so we add it to the other: {3},{1}.
Next comes 5. We will add it to {3}, so as to save the {1} for smaller numbers: {3,5},{1}.
Next comes 2. we must add it to {1}: {3,5},{1,2}. (Now we see why it was good not to add 5 to {1}.)
Next comes 4: again, we have no choice: {3,5},{1,2,4}.
Related
I'm looking for an algorithm similar to binary search but which works with data structures that are circular in nature, like a circular buffer for example. I'm working on a problem which is quite complicated, but I's able to strip it down, so it's easier to describe (and, I hope, easier to find a solution).
Let's say we have got an array of numbers with both its ends connected and an view window which can move forward and backward and which can get a value from the array (it's something like a C++ iterators which can go forward and backward). One of the values in the array is zero, which is our "sweet point" we want to find.
What we know about values in the array are:
they are sorted, which means when we move our window forward, the numbers grow (and vice versa),
they are not evenly spaced: if for example we read "16", it doesn't mean if we go 16 elements backward, we reach zero,
at last but not least: there is a point in the array where, up to that point values are positive, but after that point they are "flipped over" and start at a negative value (it is something like if we were adding ones to an integer variable until the counter goes around)
The last one is where my first approach to the problem with binary search fails. Also, if I may add, the reading a value operation is expensive, so the less often it is done the better.
PS: I'm looking for C++ code, but if You know C#, Java, JavaScript or Python and You like to write the algorithm in one of those languages, then it's no problem :).
If I understand correctly, you have an array with random access (if only sequential is allowed, the problem is trivial; that "window" concept does not seem relevant), holding a sequence of positive then negative numbers with a zero in between, but this sequence is rotated arbitrarily. (Seeing the array as a ring buffer just obscures the reasoning.)
Hence you have three sections, with signs +-+ or -+-, and by looking at the extreme elements, you can tell which of the two patterns holds.
Now the bad news: no dichotomic search can work, because whatever the order in which you sample the array, you can always hit elements of the same sign, except in the end (in the extreme case of a single element of opposite sign).
This contrasts with a standard dichotomic case that would correspond to a +- or -+ pattern: hitting two elements of the same sign allows you to discard the whole section in-between.
If the positive and negative subsequences are known to have length at least M, by sampling every M/2 element you will certainly find a change of sign and can start two dichotomies.
You can solve your problem using a galloping (exponential) search.
For simplicity I assume there are no duplicate items.
Start from the back and progress to the left in direction of smaller values. You begin with a jump of one index to the left, each next jump is exponentially bigger. With each jump to the left you should find a smaller value. If you encounter a greater value that means that zero is somewhere between the last two visited indexes. The only case when you will never encounter a greater value is when the zero is exactly at the beginning of the array.
After the jump from index i to i-j that jumped over zero, you've got a range in which zero resides. Since the jump was too far, try jumping from i to i-j/2. If that's still too far (overjumped zero) you try i-j/4 and so on. So this time each jump tried is exponentially smaller. With each step you divide the possible range where zero resides by half. On the other hand, if i-j is too far, but i-j/2 is too near (not reached zero yet), you try i-j/2-j/4. I hope you get the idea now.
This has O(lg n) complexity.
given an array of size n, n<=10^5 what is efficient approach to count number of sub arrays whose product is even ?
i am using naive approach with (On^3) time complexity ?
please suggest some efficient approach?
Be careful: from your explanation I have the impression that you are taking all sub-arrays, calculate the product and check if it is even.
However there's one very important mathematical rule: when you have a series of natural numbers, as soon as there's one even number, the product will be even.
So, I'd advise you to program following algorithm:
Search in your array for an even number.
Count the amount of sub-arrays, containing that even number.
Search in your array for the next even number.
Count the amount of sub-arrays, containing that next even number, but not containing the previous even number.
Continue until you've processed all even numbers in your array.
I want number of ways to divide an array of possitive integers such that maximum value of left part of array is greater than or equal to the maximum value of right part of the array.
For example,
6 4 1 2 1 can be divide into:
[[6,4,1,2,1]] [[6][4,1,2,1]] [[6,4][1,2,1]] [[6,4,1][2,1]] [[6,4,1,2][1]] [[6][4,1][2,1]] [[6][4][1,2,1]] [[6][4][1,2][1]] [[6][4,1,2][1]] [[6,4,1][2][1]] [[6][4,1][2][1]] [[6,4][1,2][1]]
which are total 12 ways of partitioning.
I tried a recursive approach but it fails beacause of termination due to exceed of time limit. Also this approach is not giving correct output always.
In this another approach, I took the array ,sort it in decreasing order and then for each element I checked weather it lies on right of the original array, and if does then added it's partitions to it's previous numbers too.
I want an approach to solve this, any implementation or pseudocode or just an idea to do this would be appreciable.
I designed a simple recursive algorithm. I will try to explain on your example;
First, check if [6] is a possible/valid part of a partition.
It is a valid partition because maximum element of ([6]) is bigger than remaining part's ([4,1,2,1]) maximum value.
Since it is a valid partition, we can use recursive part of the algorithm.
concatenate([6],algorithm([4,1,2,1]))
now the partitions
[[6][4,1,2,1]], [[6][4,1][2,1]], [[6][4,1][2,1]] [[6][4][1,2,1]] [[6][4][1,2][1]] [[6][4,1,2][1]]
are in our current solution set.
Check if [6,4] is a possible/valid part of a partition.
Continue like this until reaching [6,4,1,2,1].
Today my professor gave us 2 take home questions as practice for upcoming array unit in C and I am wondering what exactly the sorting algorithm these 2 problems resemble and what their Big O is. Now, I am not coming here just expecting answers and I have ALREADY solved them, but I am not confident in my answers so I will post them udner each question and if I am wrong, please correct me and explain my error in thinking.
Question 1:
If we decide to go through an array's(box) element(folders) one at a time. Starting at the first element and comparing it with the next. Then if they are the same the comparison ends, however if both are not equal then it moves on to comparing the next two ELEMENTS [2] and [3]. This process is repeated and will stop once last two elements are compared and note that the array IS already sorted by last name and we are looking for same first name! Example: [ Harper Steven, Hawking John, Ingleton Steven]
My believed answer:
I beleive it is O(n) because it's just going over the elements of an array comparing array[0] to array[1] and then array[2] to array[3] ect ect. This process is linear and continues until the last two are compared. Definitely not logn because we aren't multiplying or diving by 2.
Final Question:
Suppose we have a box of folders each containing info on one person. If we were to want to look for people with same first name, we could first start by placing a sticker on the first folder in the box and then going through the folders after it in an orderly fashion until we find person with same name. If we find a folder with same name, we move that folder next to the folder with a sticker. Once we find ONE case where two people have same name, we stop and go to sleep because we're lazy. If the first search fails however, we simply remove sticker and place it on next folder and then continue as we did earlier. We repeat this process until sticker is on last folder in a scenario where we have no two people with same name.
This array is NOT sorted and compares the first folder with sticker folder[0] with the next i folder[i] elements.
My answer:
I feel like this can't be O(n), but maybe O(n^2) where it kinda feels like we have an array and then we keep repeating the process where n is proportional to the square of the input(folders). I could be wrong here through >.>
You're right on both questions… but it would help to explain things a bit more rigorously. I don't know what the standards of your class are; you probably don't need an actual proof, but showing more detailed reasoning than "we aren't multiplying or dividing by two" never hurts. So…
In the first question, there's clearly nothing happening here but comparisons, so that's what we have to count.
And the worst case is obviously that you have to go through the whole array.
So, in that case, you have to compare a[0] == a[1], then a[1] == a[2], …, a[N-1] == a[N]. For each of N-1 elements, there's 1 comparison. That's N-1 steps, which is obviously O(N).
The fact that the array is sorted turns out to be irrelevant here. (Of course since they're not sorted by your search key—that is, they're sorted by last name, but you're comparing by first name—that was already pretty obvious.)
In the second question, there are two things happening here: comparisons, and then moves.
For the comparisons, the worst case is that you have to do all N searches because there are no matches. As you say, we start with a[0] vs. a[1], …, a[N]; then a[1] vs. a[2], …, a[N], etc. So, N-1 comparisons, then N-2, and so on down to 0. So the total number of comparisons is sum(0…N-1), which is N*(N-1)/2, or N^2/2 - N/2, which is O(N^2).
For the moves, the worst case is that you find a match between a[0] and a[N]. In that case, you have to swap a[N] with a[N-1], then a[N-1] with a[N-2], and so on until you've swapped a[2] with a[1]. So, that's N-1 swaps, which is O(N), which you can ignore because you've already got an O(N^2) term.
As a side note, I'm not sure from your description whether you're talking about an array from a[0…N], or an array of length N, so a[0…N-1], so there could be an off-by-one error in both of the above. But it should be pretty easy to prove to yourself that it doesn't make a difference.
Scenario 2, a method of finding two matching items of arbitrary value, is indeed “quadratic”. Each pass looking for a match of one candidate against all the rest of the elements is O(n). But you repeat that n times. The value of n drops as you go so a detailed number of comparisons would be closer to n+(n-1)+(n-2)+ … 1 which is (n+1)×(n/2) or ½(n²+n) but all we care about is the overall shape of the curve so don't worry about the lower order terms or the coefficients. It's O(n²).
So when balancing a KD tree you're supposed to find the median and then put all the elements that are less on the left subtree and those greater on the right. But what happens if you have multiple elements with the same value as the median? Do they go in the left subtree, the right or do you discard them?
I ask because I've tried doing multiple things and it affects the results of my nearest neighbor search algorithm and there are some cases where all the elements for a given section of the tree will all have the exact same value and so I don't know how to split them up in that case.
It does not really matter where you put them. Preferably, keep your tree balanced. So place as many on the left as needed to keep the optimal balance!
If your current search radius touches the median, you will have to check the other part, that's all you need to handle tied objects on the other side. This is usually cheaper than some complex handling of attaching multiple elements anywhere.
When doing a search style algorithm, it is often a good idea to put elements equal to your median on both sides of the median.
One method is to put median equaling elements on the "same side" as where they where before you did your partition. Another method is to put the first one on the left, and the second one on the right, etc.
Another solution is to have a clumping data structure that just "counts" things that are equal instead of storing each one individually. (if they have extra state, then you can store that extra state instead of just a count)
I don't know which is appropriate in your situation.
That depends on your purpose.
For problems such as exact-matching or range search, possibility of repetitions of the same value on both sides will complicate the query and repetition of the same value on both leaves will add to the time-complexity.
A solution is storing all of the medians (the values that are equal to the value of median) on the node, neither left nor right. Most variants of kd-trees store the medians on the internal nodes. If they happen to be many, you may consider utilizing another (k-1)d tree for the medians.