I have a m x m two-dimensional array and I want to randomly select a sequence of n elements. The elements have to be adjacent (not diagonally). What is a good approach here? I though about a depth-first search from a random starting point but that seemed a little bit overkill for such a simple problem.
If I get this right, you are looking for sequence like continuous numbers ?
When i simplyfy this:
9 4 3
0 7 2
5 6 1
So when the 1 is selected, you'd like to have path from 1 to 4 right ? I personally think that Depth-First search would be the best choice. It's not that hard, it's actually pretty simple. Imagine you select number 2. You'll remember position of number 2 and then you can look for lowest numbers until there are any. When you are done with this part, you just do the same for higher numbers.
You have two stacks one for possible ways and another one for final path.
When going through the array, you are just poping from possibilities and pushing right ones into the final stack.
The best approach would be finding the lowest possible number without saving anything and then just looking for higher numbers and storing them so at the end you'll get stack from the highest number to the lowest.
If I get that wrong and you mean just like selecting elements that are "touching" like (from my table) 9 0 7 6, which means that the content doesn't matter, then you can do it simple by picking one number, storing all possibilities (every element around it) and then pick random number from 0 to size of that stored values. When you select one, you remove it from these stored values but you keep them. Then you run this on the new element and you just add these new elements to stored elements so the random will always pick surrounding around these selected numbers.
Related
I'm working on a math problem dealing with arrangements of Males and Females. There are 5 couples and we know that each couple sit adjacent to each other , every male is seated opposite to a female . If I am to represent male or female with either +1 or -1 and want to find the list of all possible outcomes and print them, how do I go about it?
Do I have to make use of 10 FOR loops? Is there a simpler way in which I could perhaps store the results in an array?
P.S. The math question isnt limited to what I have written here, I want to solve it by myself(sorry) but I would like to understand the issue I have highlighted above. If possible show me a small snippet to point me in the right way.
The most "efficient" or "simple" way to generate all ways to get 10 numbers containing 1 or -1 depends on the language. Python has a very simple and quick way. Here is an expression that creates a generator that does this. First execute the command
import itertools
to get what you need into your namespace, then the expression is
itertools.product((1, -1), repeat=10)
For example, to work on all those tuples of 10 numbers you could do:
import intertools
for mytuple in itertools.product((1, -1), repeat=10):
# Process mytuple
If you are not familiar with Python, each "tuple" that is created for a cycle of the loop is basically equivalent to an array.
Check out the Power Set to generate all possible subsets of a set.
There are many ways to generate this, but you stated that you want to figure it out.
This link from math.stackexchange.com seems relevant
If order doesn't matter, there are eleven solutions: one for each possible number of -1 in the output list. To list these, loop from 0 to 10 (inclusive) and then loop from 1 to 10 (inclusive), first printing a number of -1 equal to the value of the outer counter, then printing 1 until the end of the inner loop.
If order does matter, a simple recursive solution is to start with an empty buffer and position zero. Then, at each level, add -1 and 1, in turn, to the current position, recursively filling the remainer of the buffer by incrementing the position in each call. When the position is equal to the buffer length (hence the buffer is full) you can print the buffer's content and terminate the recursion. This is O(n2^n) time and O(n) space, where n is the buffer length. If stack overflow becomes a concern, consider rewriting this using iteration and a stack to explicitly manage the call stack yourself.
Assume we have got an array arr with all initial values 0. Now we are given n operations - an operation consists of two numbers a b. It means that we are adding +1 to the value of arr[a] and adding -1 to the value of arr[b].
Moreover, we can swap numbers in some operations, what means that we will add -1 to arr[a] and +1 to arr[b].
We want to achieve a situation, in which all values of arr are equal to 0 even after all these operations. We are wondering if that is possible, and, if yes, what operations should we swap to achieve that.
Any thoughts on that?
Some example input:
3
1 2
3 2
3 1
should result in
YES
R
N
R
where R means to reverse that operation, and N not to do it.
input:
3
1 2
2 3
3 2
results in answer NO.
Let each of the array element be a vertex in a graph and the operation (a,b) be a edge from vertex a to b (there might be multiple edges between same vertices). Now traveling from the vertex a means decrease array element a and traveling to the vertex a means increase array element a. Now if each vertex has an even number of edges and you find a cyclic path that visits each edge exactly once you will have a zero total sum in the array.
Such a path is called Eulerian cycle (Wikipedia). From the Wikipedia: An undirected graph has an Eulerian cycle if and only if every vertex has even degree, and all of its vertices with nonzero degree belong to a single connected component. As in your case only all the disconnected sub graphs need to have an Eulerian cycle it is enough to count how many times each array index appears and if the count is even for each one of them there is always way to obtain zero total in the array.
If you want to find out which operations to reverse, you need to find one of such paths and check which directions you travel the edges.
Just count the number of times the indices appear. If all indices appear in even numbers, then the answer is YES.
You can prove it by construction. You will need to build a pair list from the original pair list. The goal is to build the list such that you can match every index that appears on the left with an index that appears on the right.
Go from the first pair to the last. For each pair, try to match an index that appears an odd number of times.
For example, in your first example, each index appears twice, so the answer is YES. To build the list, you start with (1,2). Then you look at the pair (3,2) and you know that 2 appears once on the right, so you swap it to have 2 on the left: (2,3). For the last pair, you have (3,1) which matches 1 and 3 that appear only once so far.
Note that at the end, you can always find a matching pair, because each number appears in an even number. Each number should have a match.
In the second example, 2 appears three times. So the answer is NO.
The premise of this problem is a sorted array of strings that's interspersed (in no particular order) with empty strings, like so:
["at", "", "", "", "ball", ""]
My algorithm came down to finding the midpoint, and arbitrarily running my pointer left (or right) until it landed on a non-empty string so that I can then execute a binary search.
The solutions recommended checking both left and right elements until we land on a non-empty string. Once we have a non-empty string, we can proceed with binary search.
The solutions way on average will land much quicker on a non-empty string, but it requires more calculations to get there. Consequently, I'm struggling to compare/contrast the time costs of each approach.
Which is the more optimal approach?
I guess the question is: when you land on an empty string, what algorithm visits less elements?
Suppose you have an sequence of N empty strings. With the suggested approach, if you land on the N/2th, you will visit N elements before finding a non empty string.
if you consider landing in the following positions, for each positions you end up visiting two less elements (one on the left and one on the right). So, your number of visited elements as a function of the landing position is:
{2, ... N-4, N-2, N, N-2, N-4, ...}.
If you visit only the element in a direction, your number of elements as a function of the position is {N, N-1, N-2...1}
Assuming that the probability of landing at any position in a range of empty string is the same, knowing that the sum of the first K number is
K*(K+1)
sum(1,K) = ------
2
and the average of the first K numbers is
K*(K+1)
avg(1,K) = ------ = K/2 + 1
2*K
The average in the first case is 2 * ((N/2)/2 + 1) = N/2 + 2
The average in the second case is is N/2 + 1
So, it seems to me in terms of complexity the two approaches are the same.
On a glimpse I would say that the strength of binary search is to always cut the array to search in half by querying the center element. With gaps, that is no longer possible as the center element can be a gap. So what we would want to do is find the closest non-gap element to the center. In order to do so we'd look alternatingly left and right.
position 1 2 3 4 5 6 7 8 9
value A B _ U _ _ _ T Z
Say we are looking for value B. We hit position 5 ( = (1+9)/10 ) which is a gap. If the algorithm were to always go right, then we'd walk on till position 8 and have the range to search restricted to 1-8 thus.
If on the other hand we had looked right, then left (etc.) then we'd have found position 4, which is much closer to the center and the range to search would be more restricted (1-4 in this example). Of course we can always make up an example where the always-look-right algorithm works better (e.g. when looking for T in above example :-), but generally it will be best to try to get as close to the center as possible, which is what the alternatingly-right-left solution does.
It was also suggested in a comment to remove gaps and you answered you'd have to read the whole array for this. This is true, but if you want to search the same range multiple times, that may be the fastest approach still, because you'd build that gapless arrray just once.
We'd build a new array containing the values and the original position and this array can be searched with pure binary search. Search this array several times and at one time it will pay to have built this new array.
position 1 2 3 4 5
orig. pos. 1 2 4 8 9
value A B U T Z
Even with empty strings, it is possible to perform a similar search as a binary search. When you visit an empty string, you should continue the binary search in one of the sides arbitrarily, then save that information in the stack, i.e. store whether this was a random direction or a wise direction. If at a certain point, the algorithm understands that was a wrong random direction, then tests the other direction with binary search and updates the stack of choice. If it was the right direction then just updates that stack and continues as normal binary search. This may lead to a linear time algorithm, however, depending on the distribution of the empty spaces, it may have an average of O (log n).
I encountered an interview question.
Given two sorted arrays.
Initially both have set set of elements but one element is removed from one array.
Find the element removed.
Constraint is we have to done it inplace in O(logn)
For ex:
arr1[]={1,2,3,8,12,16};
arr2[]={1,2,8,12,16};
element removed is 3
I am typing from mobile, so it is a pseudo code, but you will get it:
take arr1.len / 2. It is 3. Check arr1[3] and arr2[3]. If they equal then missing vsalue is in index greater than 3 else less than 3. Here we get 8 and 12. So missing is before. We take index 3/2=1. Compare arr1[1] and arr2[1]. They are equal, so missing is after index 1 and before 3. So it is arr1[2] = 3.
This is the idea. You are doing a binary search, deviding searvh area by half everytime. You take left or right part of the array depending on comparing. You just need to implement this and do some checks, but the idea is clear I think.
Given an array which contains all the numbers from 1 to 100 and any number from the array(1 to 100) is given.
we need to form a subset with minimum no of elements from the given array,such that we can represent the given number.
We can only add numbers from the subset to form given number if required.
We can not add element twice from the same index of the subset.
Few Examples:
Ex:given an array of elements 1,2,3.
Ans:1,2.
If the given number is 1.We can represent 1 from our subset directly.
If the given number is 2.We can represent 2 from our subset directly.
If the given number is 3.we can represent 3 with 1+2 from our subset.
We can actually duplicates the numbers while forming the subsets like
Ex:given an array of elements 1,2.
Ans:1,2 or 1,1.
The answer cannot be just 1.As we cannot add same 1 twice to form 2.
A friend of mine asked me this question and I am stuck on how to procede..
Any suggestions would greatly help ...
Also I could not come up some decent title for this question..Is this a classical problem?
You can solve this in a greedy manner: Repeatedly choose the first missing value.
It is not clear whether your array contains all the numbers from 1 to 100, or just a subset of them.
It is also not clear whether you have to make all numbers from 1 to the largest number in the array, or just a few target values. I will assume you have to be able to construct all the intermediate values as well.
Assuming all numbers are present
First we must include the number 1.
Next we include the number 2. We can now make everything up to 3.
So next include the number 4. We can now make everything up to 1+2+4=7.
So next include the number 8. We can now make everything up to 1+2+4+8=15.
...
So next include the number 2^k. We can now make everything up to 1+2+...+2^k = 2^(k+1).
So for 100 numbers you will need 1,2,4,8,16,32,64 and will be able to make every number up to 127.
Assuming a subset of numbers are present
Suppose the array might be a subset such as [1,2,3,5,7,9,15]. The same basic approach works, but this time we need to choose the largest number in the array that is less than or equal to the first missing value.
First include 1.
Next include 2, we can now make numbers up to 3.
Next our first missing value is 4, but we don't have a 4 to pick, so instead pick the 3. We can now reach up to 1+2+3=6.
Next our first missing value is 7, so we can pick the 7. Our reach is now 1+2+3+7=13.
Next our missing value is 14, but we don't have a 14, so instead pick the 9, etc.