Use of Handshaking Lemma to find number of subarrays with even Sum - java

I was attempting to do practice questions and came across a solution I do not understand the reasoning behind.
The question can be found here, finding the number of even sum subarrays.
https://www.geeksforgeeks.org/find-number-subarrays-even-sum/
Questions related have been asked, but I am asking specifically about the use of the handshaking lemma at the end of the solution.
I understand that we build a count of the even and odd sum subarrays, but do not get why we use the hand shaking lemma to compute the number of even sum subarrays. If we get a count of even and odd cumulative sums, how does the handshaking lemma exactly play into this? Clearly, an even sum subarray is made of either odd + odd, even + even, or a lone even value, so I would just like to know how exactly all cases are being accounted for in this specific scenario. Thanks for your help!

First we have an array of numbers, for example:
[1,3,5,2,10,7]
So, how to count the number of subarray with even sum?
Let's convert it into another array called sum, which the value at index ith is the sum of subarray from 0 to ith index
[1,4,9,11,21,28]
Clearly, we can see that for a subarray from range a to b, the sum of this subarray is even if and only if sum[b] - sum[a - 1] is even.
Now, let imagine that a graph connecting between odd and odd entry in sum and even and even in sum -> the number of edges in this graph is the answer for this problem.
So, from the handshake lemma, 2*E = sum of all vertexes degree
The degree of each odd vertex is number of odd vertex - 1
The degree of each even vertex is number of even vertex - 1
=> so
2*E = odd*(odd - 1) + even*(even - 1) => E = odd*(odd - 1)/ 2 + even*(even - 1)/2
Another way to understand this is for odd entries, the number of ways to choose odd - odd pairs is C(odd, 2) = odd*(odd - 1)/2 with C is the combination

Related

Express any odd number greater than 5 as the sum of 3 primes

For a given odd number n I want to efficiently compute 3 primes whose sum is equal to n. If there are multiple solutions then I want the one with the smallest primes (I want 2+2+17=21 instead of 3+5+13=21)
This is always possible forn>5.
My current approach is to reduce the problem to computing 2 primes whose sum is equal to n-3 and then I simply output the 2 computed primes and 3 since they obviously sum up to n. I choose 3 since it is the smallest odd prime and when I subtract it from n I get an even number, therefore it should be part of every solution I'm looking for. I'm using this to compute the sum of 2 primes, it works if n is even which it is in my case (since I subtracted 3 from an odd n).
My approach doesn't work since there are solutions without a 3 as a summand (41=2+2+37).
Is there a straightforward approach which I'm missing?
First test whether n-4 is prime. If so, your answer is {2, 2, n-4}. Otherwise, your original approach will work. You'll never use just one 2 because your sum would be even.

Sorting algorithm, insertion sort

ive been trying to the problem and have become stuck. The specification of the problem is a as follows
Median of k numbers is defined as the (k/2)th
smallest number if k is even; and the ((k+1)/2)th
smallest number if k is
odd. For example, median of the 4 numbers: 2 1 8 7 is the 2nd smallest number i.e. 2, and the median of the 5
numbers: 2 1 8 7 6 is the 3rd smallest number i.e. 6.
In this problem, you'll be given N numbers. Let the kth
median or m(k) be defined as the median of the first k
numbers (1<=k<=N). i.e. the 5th
median or m(5) is the median of the first 5 numbers, the 8th
median or m(8) is the
median of the first 8 numbers, etc. In other words, let Ai
denote the ith
number, then the kth
median or m(k) is
defined as the median of the numbers A1, A2, ā€¦, Ak.
Your task is to find m(1) + m(2) + m(3) + ...+ m(n), output the sum modulo 100000
so basically you have to read in numbers, first number is stored in the variable N and dictates how many numbers to be read in after that point is. (this is always 5). Then you must iterate through the reading in of the numbers, storing them in array, then sorting them and then finding the median of the median and then store the value in the and repeating until all numbers have been read in, sorted and median found.
I have managed to read the numbers in fine and i am able to sort them to some degree but my sorting algorithm, sorts them highest values first and smallest values last and in order to get the program to run properly to get the desired output i need it to be the other way round and i cant work out how.
The numbers read in will be like so
5
10
5
1
2
15
and the answer would be 27.
This is my code
Any help on this problem would be amazing because im just going round in cirles, btw the System.out.println(myIntArray [4]) etc is just a tracer to see how the sorting is taking place
You seem to be sorting the entire array each time through. You need to sort from 0 to i (exclusive) at each iteration. Also, for odd length, you need parentheses when computing the subscript: myIntArray[(i+1)/2] instead of myIntArray[i+1/2]. Because of operator precedence, Java will evaluate the latter as myIntArray[i+(1/2)], which is just myIntArray[i], since 1/2 is 0 in integer division.

Finding smallest delta available for permutations of a set of numbers

Presume we have a set of 12 objects, lets say {1,2,3,4,5,6,7,8,9,10,11,12}. We must break this set into 4 smaller ones composed of three objects, so that the largest sum and smallest sum of these four sets is minimized. We must find this difference. In our example, {1,7,12},(3,8,9},{4,5,10},{2,6,11}. These four sets satisfy the problem since their sums are 20 and 19, meaning a delta of 1, our answer.
How can one solve this problem for any arbitrary 12 values?
I've tried enumerating all partitions of said set into 4 sets of 3, and finding one with the optimal score. However, time is of the essence, and so I was wondering how one would approach this problem in Java
I don't have exact code on me right now, but what it essentially was was 9 nested for loops, where the first three that nest are one set, the next three are the next set, the last three are another set, and the three left overs are another set. I used a 2D array so that values would be in score[i][0] and score[i][1] would act as an indicator to let me know if that value in score[i][0] had already been placed into a set.
This of course gets tedious and inefficient.
You could easily simplify the problem by finding the values that the sums must approach for a better optimisation :
For instance, in your simple case (1,2...12), then the total sum of every terms is 78. Thus, Each groups must have a sum very close to 78/4=19.
So, let's try a very simple algorithm :
- compute TOTAL_SUM = SUM(terms)
- compute TARGET_SUM = TOTAL_SUM / number(terms)
- set DELTA=0
- loop {
- Try to split terms in groups where TARGET_SUM - DELTA <= SUM <= TARGET_SUM + DELTA
- if a solution is found, exit
- DELTA = DELTA + 1
- }
Ok, I did not helped you much with this "Try to split..." step. But it should look like you own solution, except that you have additional constraints which can help you to speed up the process.
Hope this helps.

Find all differences in an array in O(n)

Question: Given a sorted array A find all possible difference of elements from A.
My solution:
for (int i=0; i<n-1; ++i) {
for (int j=i+1; j<n; ++j) {
System.out.println(Math.abs(ai-aj));
}
}
Sure, it's O(n^2), but I don't over count things at all. I looked online and I found this: http://www.careercup.com/question?id=9111881. It says you can't do better, but at an interview I was told you can do O(n). Which is right?
A first thought is that you aren't using the fact that the array is sorted. Let's assume it's in increasing order (decreasing can be handled analogously).
We can also use the fact that the differences telescope (i>j):
a_i - a_j = (a_i - a_(i-1)) + (a_(i-1) - a_(i-2)) + ... + (a_(j+1) - a_j)
Now build a new sequence, call it s, that has the simple difference, meaning (a_i - a_(i-1)). This takes only one pass (O(n)) to do, and you may as well skip over repeats, meaning skip a_i if a_i = a_(i+1).
All possible differences a_i-a_j with i>j are of the form s_i + s_(i+1) + ... + s_(j+1). So maybe if you count that as having found them, then you did it in O(n) time. To print them, however, may take as many as n(n-1)/2 calls, and that's definitely O(n^2).
For example for an array with the elements {21, 22, ..., 2n} there are nā‹…(n-1)/2 possible differences, and no two of them are equal. So there are O(n2) differences.
Since you have to enumerate all of them, you also need at least O(n2) time.
sorted or unsorted doesn't matter, if you have to calculate each difference there is no way to do it in less then n^2,
the question was asked wrong, or you just do O(n) and then print 42 the other N times :D
You can get another counter-example by assuming the array contents are random integers before sorting. Then the chance that two differences, Ai - Aj vs Ak - Al, or even Ai - Aj vs Aj - Ak, are the same is too small for there to be only O(n) distinct differences Ai - Aj.
Given that, the question to your interviewer is to explain the special circumstances that allow an O(n) solution. One possibility is that the array values are all numbers in the range 0..n, because in this case the maximum absolute difference is only n.
I can do this in O(n lg n) but not O(n). Represent the array contents by an array of size n+1 with element i set to 1 where there is a value i in the array. Then use FFT to convolve the array with itself - there is a difference Ai - Aj = k where the kth element of the convolution is non-zero.
If the interviewer is fond of theoretical games, perhaps he was thinking of using a table of inputs and results? Any problem with a limit on the size of the input, and that has a known solution, can be solved by table lookup. Given that you have first created and stored that table, which might be large.
So if the array size is limited, the problem can be solved by table lookup, which (given some assumptions) can even be done in constant time. Granted, even for a maximum array size of two (assuming 32-bit integers) the table will not fit in a normal computer's memory, or on the disks. For larger max sizes of the array, you're into "won't fit in the known universe" size. But, theoretically, it can be done.
(But in reality, I think that Jens Gustedt's comment is more likely.)
Yes you can surely do that its a little tricky method.
to find differances in O(n) you will need to use BitSet(C++) or any similar Data Structure in respective language.
Initialize two bitset say A and B
You can do as follows:
For each iteration through array:
1--store consecutive differance in BitSet A
2--LeftShift B
3--store consecutive differance in BitSet B
4--take A=A or B
for example I have given code-
Here N is Size of array
for (int i=1;i<N;i++){
int diff = arr[i]-arr[i-1];
A[diff]=1;
B<<=diff;
B[diff]=1;
A=A | B;
}
Bits in A which are 1 will be the differances.
First of all the array need to be sorted
lets think a sorted array ar = {1,2,3,4}
so what we were doing at the O(n^2)
for(int i=0; i<n; i++)
for(int j=i+1; j<n; j++) sum+=abs(ar[i]-ar[j]);
if we do the operations here elaborately then it will look like below
when i = 0 | sum = sum + {(2-1)+(3-1)+(4-1)}
when i = 1 | sum = sum + {(3-2)+(4-2)}
when i = 2 | sum = sum + {(4-3)}
if we write them all
sum = ( -1-1-1) + (2+ -2-2) + (3+3 -3) + (4+4+4 )
we can see that
the number at index 0 is added to the sum for 0 time and substracted from the sum for 3 time.
the number at index 1 is added to the sum for 1 time and substracted from the sum for 2 time.
the number at index 2 is added to the sum for 2 time and substracted from the sum for 1 time.
the number at index 3 is added to the sum for 3 time and substracted from the sum for 0 time.
so for we can say that,
the number at index i will be added to the sum for i time
and will be substracted from the sum for (n-i)-1 time
Then the generalized expression for
each element will be
sum = sum + (i*a[i]) ā€“ ((n-i)-1)*a[i];

Algorithm which tells if a number is obtainable from a given set using only '+' ,'*' and brackets

I have two list of numbers, for every member of the second one I must tell if it's obtainable using all the numbers of the first one and placing '+' or '*' and as many '(' ')' I want.
I can't change the order .
List1 can contain a max of 20 elements beetween 1 and 100.
List2 can contain max 5 elements beetween 1 and 20'000.
EX:
List1=[2 4 3 5]
List2=[19 15 24]
19-> 2+(4*3)+5 YES
15 NO
24->2*(4+3+5) YES
With brute force it takes ages to handle inputs with List1 larger than 10.
edit: numbers are always positive.
edit:
I find the max and min numbers that are obtainable from the list and then I discard all the possibilities that have the target outside this range, then I try all the remaining ones.
MAX=n1*n2*n3*....*ni if there are 1 thei r added to their smallest neighbour
MIN=n1+n2+....+ni 1 excluded
Still it's not fast enough when input are big (List1 longer than 10 or numbers in List2 bigger than 10000)
For each sublist of List1, compute the numbers between 1 and 20,000 that can be made with that sublist. The resulting DP bears resemblance to CYK.
I'm being somewhat vague here because this is almost certainly a programming contest problem.
#u mad is correct, but I'll give a little more detail.
Suppose that n = size of list 1. For each 0 <= i < j < n you need to compute all of the distinct values in the range (1..20_000) that can be made from the numbers in the interval [i, j-1]. You can do this with recursion and memoization.
Once you've done this then the problem is easy.
You could try a smart brute force which discards sets of equations by chunks.

Categories