Got this as an homework assignment and not really sure where to start!
Given the set {1,2,3,4}, you can form six combinations of length two from that set, viz:
{1,2},{1,3},{1,4},{2,3},{2,4},{3,4}
If I was to choose one of the combinations, ({1,2} for example), how can I tell how many of the others are not disjoint to it? In this case it is four: {1,3},{1,4},{2,3}{2,4}
Not really sure about how to go about this mathematically, any pointers in the right direction would be much appreciated.
Number of subsets that can be formed from a set of n items taking r items at a time is
total = P(n, r) = n! / (r! * (n - r)!)
Let s be the selected combination. To find the number of subsets that are not disjoint with s, we start by finding the number of subsets that are disjoint with s - those sets that doesn't have any items in s (lets call that number k). Thus k is the number of subsets that can be formed from a set of n - r items, taking r at a time.
k = P(n - r, r) = (n - r)! / (r! * (n - r - r)!)
= (n - r)! / (r! * (n - 2r)!)
Thus, the number of subsets disjoint with the selected set is:
total - k = P(n, r) - P(n - r, r)
Remember that this includes the selected subset s. Subtract one from this to get the number of disjoint sets with s.
Consider the following example:
//Let n = 6 and r = 2
total = P(n, r) = n! / (r! * (n - r)!) = 6! / (2! * 4!) = 15
k = P(n - r, r) = (n - r)! / (r! * (n - 2r)!) = 4! / (2! * 2!) = 6
answer = 15 - 6 = 9;
answer excluding the selected set s = 8
//Super set:
{123456}
//Possible sub sets:
{12,13,14,15,16,23,24,25,26,34,35,36,45,46,56} //15 items
//Let the selected set be {12}, then sets without 1 and 2:
{34,35,36,45,46,56} //6 items
//9 sets (including the selected set) are not disjoint with the selected set
Maybe start by reading some book or articles on combinatorics ..
If you can program, this library will help you.
I would do something like this:
For each item in my combination ( 1 then 2 ) do the following
* For each item in the set (1, 2, 3, then 4) do the following
** if set item is different from both combination item 1 and 2
*** print out combination item and print out set item
Try Combinatorics or better Permutations.
The sets X = {a, b} and Y are disjoint if a and b both do not appear in Y. Therefore, X and Y are not disjoint if a appears in Y or b appears in Y.
To find out how many other sets are not disjoint with {a, b}, consider all the possibilities: In general all the sets with two elements that are not disjoint with {a, b} are of the form {a, x} or {b, x}, for any x in the original set. If the original set had n elements, then there are n possibilities for {a, x} and another n for
{b, x}, for a total of 2*n*.
However, {a, b} is both of the form {a, x} (for x = b) and of the form {b, x} (for x = a), so we are counting it twice. We must count it zero times, because {a, b} is the same set as the one we were starting with. So we subtract 2, for a total of 2*n* - 2.
But we're still counting {a, a} (for x = a) and {b, b} (for x = b). But those only contain one element each ({a, a} = {a} and {b, b} = {b}), so we shouldn't count them. Therefore we subtract 2, for a total of 2*n* - 4.
For your example, {1, 2, 3, 4} gives n = 4, so the number of elements not disjoint with {1, 2} is 2*4 - 4 = 4.
Related
given an array A of size n and another array called B.
B is made of array A and 2 constants x and y where Bi = x * Ai + c (i => 0,1,2, … N-1)
For example,
if A : {3, 1, 5, 7} and x = 1 and y =2, then B : {5, 3, 7 ,9}
question: find out how many times A (j+1), (j+2), …. (n -1) > Bj for j E {0, 1, … n-1 }
Using the sample input above
A: {3,1,5,7}
B: {5,3,7,9}
the answer would be 3 since
when j = 0, A3 > B0 (7>5)
when j = 1, A2 > B1 (5>3) and A3 > B1 (7>3)
since there are only 3 possibilities of A j+1 …. n -1 > Bj for j E {0, 1, … n-1 }, the output will be 3
is there a way to solve this with an algorithm below O(n^2)? thanks!
Why not insert elements of B into an order statistic tree as we iterate on A, and look up for each element we see in A, how many in the tree are lower? At each A_i, make sure all but only elements up to B_(i-1) are in the tree before the lookup. This wouldn't distinguish which Bs have higher A elements, but it seems like the question is only asking for the total number. O(n log n) time, O(n) extra space.
I had an interview and I was not able to give a best approach for the problem.
A=1, B=0
- Operation L: A=2A-B
- Operation R: B=2B-A
For each step, only one operation(L or R) is taken place.
For a given number N, what is the minimum number of operations required to make A or B equals to N?
The most important one is an efficiency.
Thanks in advance.
In k operations you can get all values of N in [-(2^k)+1, 2^k].
Notice that abs(A) + abs(B) = 2^k for all possible k paths, and that A & B exactly cover the range [-(2^k)+1, 2^k] in the set of paths of length k.
k=0: (1,0)
k=1: (1,-1), (2,0)
k=2: (1,-3), (2,-2), (3,-1), (4,0)
etc...
Given N we can find the minimum k via log. Then we know the final pair is (N, N - 2^k) (or (N-2^k, N) if N <= 0). It's easy to follow the path back up to k=0 because one of the two elements will be out of range for the next smaller k.
E.g., N = 35.
Log2(35) = 5.13, so we use k=6.
2^6 = 64, so our final pair is (35, -29)
(35,-29) -> (3,-29) -> (3, -13) -> (3, -5) -> (3,-1) -> (1,-1) -> (1,0)
Figuring out k is O(1), finding the path is O(k) which is O(log(abs(N)).
It's not likely you need to prove anything in an interview, but if you did, you could use this:
By observation: A - B = 2^k for k steps observed for small k.
Then via induction: we have some valid (A, B) s.t. A-B = 2^k. Then L gets us (2A-B, B), but 2A-B-B = 2A-2B = 2(A-B) = 2^(k+1) as desired. Similarly for R.
It would be a challenging task for an interview but I would start with the recursion of trying to find the origin from the result. Given valid (A', B), where A' is the target we are after,
A' = 2A - B
for some A, which means that
A = (A' + B) / 2
The latter tells us that all (A' + B) in the path must be divisible by 2, and since the path ends (starts) at 1, all the (A' + B) in it are powers of 2.
Another property we can observe, although it may not be relevant to the solution is that once we switch in the first step to (even, even) or (odd, odd), we cannot switch back.
My data structure is a path represented by a list of cities. If, for example, the cities are
A, B, C, D
A possible configuration could be: A, B, D, C or D, C, A, B.
I need two compare two paths in order to find the differences between these two, in such a way that the output of this procedure returns the set of swapping operations necessary to transform the second path into the first one.
For example, given the following paths:
X = {A, B, D, C}
Y = {D, C, A, B}
indexes = {0, 1, 2, 3}
A possible way to transform the path Y into X would be the set of the following swaps: {0-2, 1-3}.
{D, C, A, B} --> [0-2] --> {A, C, D, B} --> [1-3] --> {A, B, D, C}
Is there any known (and fast) algorithm that allows to compute this set?
Your problem looks like a problem of counting the minimal number of swaps to transform one permutation to another.
In fact it's a well known problem. The key idea is to create new permutation P such that P[i] is the index of X[i] city in the Y. Then you just calculate the total number of cycles C in the P. The answer is the len(X) - C, where len(X) is the size of X.
In your case P looks like: 3, 4, 1, 2. It has two cycles: 3, 1 and 4, 2. So the answer is 4 - 2 = 2.
Total complexity is linear.
For more details see this answer. It explains this algorithm in more details.
EDIT
Okay, but how we can get swaps, and not only their number? Note, that in this solution we reorder each cycle independently doing N - 1 swaps if the length of cycle is N. So, if you have cycle v(0), v(1), ..., v(N - 1), v(N) you just need to swap v(N), v(N - 1), v(N - 1), v(N - 2), ..., v(1), v(0). So you swap cycle elements in reverse order.
Also, if you have C cycles with lengths L(1), L(2), ..., L(C) the number of swaps is L(1) - 1 + L(2) - 1 + ... + L(C) - 1 = L(1) + L(2) + ... + L(C) - C = LEN - C where LEN is the length of permutation.
I'm given the size N of the multiset and its sum S. The elements of the set are supposed to be continuous, for example a multiset K having 6 (N=6) elements {1,1,2,2,2,3}, so S=11 (the multiset always contains first N repeating natural numbers).
How can I know the total changes to make so that there can be no repetitions and the set becomes continuous?
For the above example the multiset K needs 3 changes. Hence, finally the set K will become {1,2,3,4,5,6}.
What I did is, I found out the actual sum (i.e. n*(n+1)/2) and subtracted the given sum. Let it be T.
Then, T=ceil(T/n), then the answer becomes 2*T, it is working for most cases.
But, I guess I'm missing some cases. Does there exists some algorithm to know how many elements to change?
I'm given only the size and sum of the multiset.
As you already noticed, for a given N, the sum should be S' = N * (N-1) / 2. You are given some value S.
Clearly, if S' = S the answer is 0.
If S'- S <= N - 1, then the multiset that requires least changes is
{1, 2, ..., N-1, X}
where X = N - (S' - S), which is in the range [1, N-1]. In other words, X makes up for the difference in sum between the required and the actual multiset. Your answer would be 1.
If the difference is larger than N-1, then also N-1 cannot be in the multiset. If S'- S <= (N - 1) + (N - 2), a multiset that requires least changes is
{1, 2, ..., N-2, 1, X}
where X = N + (N - 1) - (S'- S), which is in the range [1, N-2]. Your answer would be 2.
Generalizing, you would get a table like:
S' - S | answer
-----------------------
[ 0, 0] | 0
[ 1, N-1] | 1
[ N, 2N-3] | 2
[2N-2, 3N-6] | 3
and so on. You could find a formula to get the answer in terms of N and S, but it seems much easier to use a simple loop. I'll leave the implementation to you.
I am solving a competitive programming problem, it was described like this:
Given n < 10^5 integer a1, a2, a3, ..., an and L, R. How many
subarrays are there such that sum of its element in range [L, R].
Example:
Input:
n = 4, L = 2, R = 4
1 2 3 4
Output: 4
(4 = 4, 3 = 1 + 2 = 3, 2 = 2)
One solution I have is bruteforce, but O(n^2) is too slow. What data structures / algorithms should I use to solve this problem efficiently ?
Compute prefix sums(p[0] = 0, p[1] = a1, p[2] = a1 + a2, ..., p[n] = sum of all numbers).
For a fixed prefix sum p[i], you need to find the number of such prefix sums p[j] that j is less than i and p[i] - R <= p[j] <= p[i] - L. One can do it in O(log n) with treap or another balanced binary search tree.
Pseudo code:
treap.add(0)
sum = 0
ans = 0
for i from 1 to n:
sum += a[i]
left, right = treap.split(sum - R)
middle, right = right.split(sum - L)
ans += middle.size()
merge left, middle and right together
treap.add(sum)
We can do it in linear time if the array contains positive numbers only.
First build an array with prefix sum from left to right.
1. Fix three pointers, X, Y and Z and initialize them with 0
2. At every step increase X by 1
3. While sum of numbers between X and Y are greater than R keep increasing Y
4. While sum of numbers between X and Z are greater than or equal to L, keep increasing Z
5. If valid Y and Z are found, add Z - Y + 1 to result.
6. If X is less than length of the array, Go to step 2.