Maximizing difference of sums - algorithm

Given a list of N distinct positive integers, partition the list into two
sublists of n/2 size such that the difference between sums of the sublists
is maximized.
Assume that n is even and determine the time complexity.
I know, I know, it's a homework question. But the issue is not necessarily in solving it, but in understanding what exactly is being asked. I can safely say that half of the problem is simple to solve, but I don't think I get what is meant by
such that the difference between sums of the sublists
is maximized.
Any help in illustrating the "plan of attack" on this would be appreciated

asuume you have this list
list : 1 ,1 , 2, 3, 1, 5, 6, 1, 2, 20
it means you can split it to sub lists with size of n/2 in many ways
such like this
sub list 1 : 3, 1, 5, 6, 1
sub list 2 : 1 ,1 , 2, 2, 20
now calculate sum of each sub list
sum of sub list 1 is 16
sum of sub list 2 is 26
diffrence between them is : 10
but question want two sub lists such has this condition
question condition : difference between sums of the sublists is maximized.
it means between all ways that we can split main list into two sublists choose one way that has the question condition.
for example if we split above list into this lists
sub list 1 : 1 ,1 ,1 ,1 , 2
sub list 2 : 2, 3, 5 , 6 , 20
sum of sub list 1 is 6
sum of sub list 2 is 36
diffrence between them is : 30
which is more than last result and also is maximum

Related

How do i derive an expression for the worst case number of comparisons needed to merge two sorted arrays of length n/2

merge sort uses divide and conquer approach
The worst case number of comparisons needed to merge two sorted arrays of length 𝑛/2 is 𝑛−1.
This is because when two values have been compared with each other, one of those two values will never be used in a comparison again: it is the value that follows the sorted order... and it is no longer part of the rest of the merge process.
In the worst case, the last comparison will be between the last value of the first array and the last value of the second array. All the other (𝑛−2) values were already excluded from further comparisons, so that means we already did 𝑛−2 comparisons. Now the last one executes, which completes the comparison count to be 𝑛−1.
Example of a worst case input
𝑛 = 10
A = [0, 2, 4, 6, 8]
B = [1, 3, 5, 7, 9]
Comparisons during the merge:
0 1
2 1
2 3
4 3
4 5
6 5
6 7
8 7
8 9
Example of a best case input
Just to put this in perspective, the best case occurs when the last value of the first array is less than the first value of the second array (or vice versa). This only needs 𝑛 / 2 comparisons.
𝑛 = 10
A = [0, 1, 2, 3, 4]
B = [5, 6, 7, 8, 9]
Comparisons during the merge:
0 5
1 5
2 5
3 5
4 5
No more comparisons are now needed, because the first list has no more values; only the values of the second list remain: but they don't need to be compared with anything, and can be appended to the result in the order they currently occur.
Remark
The fact that this process is used as part of merge sort -- implementing a divide and conquer algorithm -- is just background info. Merging two sorted lists can be needed in other contexts that do not relate to merge sort.

Convert the permutation sequence A to B by selecting a set in A then reversing that set and inserting that set at the beginning of A

Given the sequence A and B consisting of N numbers that are permutations of 1,2,3,...,N. At each step, you choose a set S in sequence A in order from left to right (the numbers selected will be removed from A), then reverse S and add all elements in S to the beginning of the sequence A. Find a way to transform A into B in log2(n) steps.
Input: N <= 10^4 (number of elements of sequence A, B) and 2 permutations sequence A, B.
Output: K (Number of steps to convert A to B). The next K lines are the set of numbers S selected at each step.
Example:
Input:
5 // N
5 4 3 2 1 // A sequence
2 5 1 3 4 // B sequence
Output:
2
4 3 1
5 2
Step 0: S = {}, A = {5, 4, 3, 2, 1}
Step 1: S = {4, 3, 1}, A = {5, 2}. Then reverse S => S = {1, 3, 4}. Insert S to beginning of A => A = {1, 3, 4, 5, 2}
Step 2: S = {5, 2}, A = {1, 3, 4}. Then reverse S => S = {2, 5}. Insert S to beginning of A => A = {2, 5, 1, 3, 4}
My solution is to use backtracking to consider all possible choices of S in log2(n) steps. However, N is too large so is there a better approach? Thank you.
For each operation of combined selecting/removing/prepending, you're effectively sorting the elements relative to a "pivot", and preserving order. With this in mind, you can repeatedly "sort" the items in backwards order (by that I mean, you sort on the most significant bit last), to achieve a true sort.
For an explicit example, lets take an example sequence 7 3 1 8. Rewrite the terms with their respective positions in the final sorted list (which would be 1 3 7 8), to get 2 1 0 3.
7 -> 2 // 7 is at index 2 in the sorted array
3 -> 1 // 3 is at index 0 in the sorted array
1 -> 0 // so on
8 -> 3
This new array is equivalent to the original- we are just using indices to refer to the values indirectly (if you squint hard enough, we're kinda rewriting the unsorted list as pointers to the sorted list, rather than values).
Now, lets write these new values in binary:
2 10
1 01
0 00
3 11
If we were to sort this list, we'd first sort by the MSB (most significant bit) and then tiebreak only where necessary on the subsequent bit(s) until we're at the LSB (least significant bit). Equivalently, we can sort by the LSB first, and then sort all values on the next most significant bit, and continuing in this fashion until we're at the MSB. This will work, and correctly sort the list, as long as the sort is stable, that is- it doesn't change the order of elements that are considered equal.
Let's work this out by example: if we sorted these by the LSB, we'd get
2 10
0 00
1 01
3 11
-and then following that up with a sort on the MSB (but no tie-breaking logic this time), we'd get:
0 00
1 01
2 10
3 11
-which is the correct, sorted result.
Remember the "pivot" sorting note at the beginning? This is where we use that insight. We're going to take this transformed list 2 1 0 3, and sort it bit by bit, from the LSB to the MSB, with no tie-breaking. And to do so, we're going to pivot on the criteria <= 0.
This is effectively what we just did in our last example, so in the name of space I won't write it out again, but have a look again at what we did in each step. We took the elements with the bits we were checking that were equal to 0, and moved them to the beginning. First, we moved 2 (10) and 0 (00) to the beginning, and then the next iteration we moved 0 (00) and 1 (01) to the beginning. This is exactly what operation your challenge permits you to do.
Additionally, because our numbers are reduced to their indices, the max value is len(array)-1, and the number of bits is log2() of that, so overall we'll only need to do log2(n) steps, just as your problem statement asks.
Now, what does this look like in actual code?
from itertools import product
from math import log2, ceil
nums = [5, 9, 1, 3, 2, 7]
size = ceil(log2(len(nums)-1))
bit_table = list(product([0, 1], repeat=size))
idx_table = {x: i for i, x in enumerate(sorted(nums))}
for bit_idx in range(size)[::-1]:
subset_vals = [x for x in nums if bit_table[idx_table[x]][bit_idx] == 0]
nums.sort(key=lambda x: bit_table[idx_table[x]][bit_idx])
print(" ".join(map(str, subset_vals)))
You can of course use bitwise operators to accomplish the bit magic ((thing << bit_idx) & 1) if you want, and you could del slices of the list + prepend instead of .sort()ing, this is just a proof-of-concept to show that it actually works. The actual output being:
1 3 7
1 7 9 2
1 2 3 5

Find the number of non-decreasing and non-increasing subsequences in an array

I am attempting to complete a programming challenge from Quora on HackerRank: https://www.hackerrank.com/contests/quora-haqathon/challenges/upvotes
I have designed a solution that works with some test cases, however, for many the algorithm that I am using is incorrect.
Rather than seeking a solution, I am simply asking for an explanation to how the subsequence is created and then I will implement a solution myself.
For example, with the input:
6 6
5 5 4 1 8 7
the correct output is -5, but I fail to see how -5 is the answer. The subsequence would be [5 5 4 1 8 7] and I cannot for the life of me find a means to get -5 as the output.
Problem Statement
At Quora, we have aggregate graphs that track the number of upvotes we get each day.
As we looked at patterns across windows of certain sizes, we thought about ways to track trends such as non-decreasing and non-increasing subranges as efficiently as possible.
For this problem, you are given N days of upvote count data, and a fixed window size K. For each window of K days, from left to right, find the number of non-decreasing subranges within the window minus the number of non-increasing subranges within the window.
A window of days is defined as contiguous range of days. Thus, there are exactly N−K+1 windows where this metric needs to be computed. A non-decreasing subrange is defined as a contiguous range of indices [a,b], a<b, where each element is at least as large as the previous element. A non-increasing subrange is similarly defined, except each element is at least as large as the next. There are up to K(K−1)/2 of these respective subranges within a window, so the metric is bounded by [−K(K−1)/2,K(K−1)/2].
Constraints
1≤N≤100,000 days
1≤K≤N days
Input Format
Line 1: Two integers, N and K
Line 2: N positive integers of upvote counts, each integer less than or equal to 10^9
Output Format
Line 1..: N−K+1 integers, one integer for each window's result on each line
Sample Input
5 3
1 2 3 1 1
Sample Output
3
0
-2
Explanation
For the first window of [1, 2, 3], there are 3 non-decreasing subranges and 0 non-increasing, so the answer is 3. For the second window of [2, 3, 1], there is 1 non-decreasing subrange and 1 non-increasing, so the answer is 0. For the third window of [3, 1, 1], there is 1 non-decreasing subrange and 3 non-increasing, so the answer is -2.
Given a window size of 6, and the sequence
5 5 4 1 8 7
the non-decreasing subsequences are
5 5
1 8
and the non-increasing subsequences are
5 5
5 4
4 1
8 7
5 5 4
5 4 1
5 5 4 1
So that's +2 for the non-decreasing subsequences and -7 for the non-increasing subsequences, giving -5 as the final answer.

Count the coins including permutations of the same sequence

I've found a code to find number of possibilities to make change using given coins: How to count possible combination for coin problem. But how to count it, if we think about different permutations of the same sequence? I mean that, e.g. amount is 12, and "4 4 2 2" and "4 2 4 2" should be counted as 2, not 1.
As you've mentioned inside your question you can count the possible combinations as stated in How to count possible combination for coin problem. But in order to include the permutations into your answer:
If you distinguish the permutation of the same numbers [1 7 7] and [1 7 7] e.g. just count each sequence([1 7 7] here) as n! (n = # of elements in the sequence) [instead of 1]
Otherwise : multiply each sequence by n!/(m!l!...) where m = number of equal elements of type 1, l is number of equal elements of type 2 and so on... . For example for sequence like [a b b c c c] you should count this 6!/(2!*3!) [instead of 1]
So use the algorithm inside that link, that I don't repeat again, but just instead of counting each combination as 1 use the formula that I said (depending on the case you desire).
(! is factorial.)

Maximize the sum of product of adjacent numbers

Here is a question that I encountered during an Interviewstreet codesprint.
I was unable to find a a solution or even think in its direction. I'd be thankful if someone could help me find the soultion, or explain me how the problem neeeds to be dealt with.
Given numbers 1, 2, 3, .., N, arrange them in a order such that the
sum of product of adjecent numbers is maximized.
For example: if N = 3, and we order them as ( 1, 2, 3 ), the sum of
products is 1*2 + 2*3 = 8 and if we order them as ( 1, 3 ,2 ) the sum
of products is 1*3 + 3*2 = 9.
Input format :
First line of the input contains T, the number of test-cases. Then
follow T lines, each containing an integer N.
Output format :
For each test case print the maximum sum of product of adjacent
numbers.
Sample input :
2 2 4
Sample output :
2 23
Explanation :
In first test case given permutation is ( 1, 2 ). So maximum sum of
product is 1*2. In Second test case the numbers are (1,2,3,4).
Arrangement 1,3,4,2 has sum of product of adjacent numbers as
1*3+3*4+4*2 = 23. No other arrange has sum of product of adjacent
numbers more than 23.
Constraints :
1 <= T <= 10 1 <= N <= 200000
The maximum sum-of-adjacent-products comes when the largest value is in the middle of the sequence, and the successively lower values alternate to its left and right. That is, your sequence for a given value n would be [..., n-3, n-1, n, n-2, n-4, ...] (or the reverse of this, which will have the same sum of products).
So, leaving out the input-parsing bits, here's the heart of the algorithm (in Python, but easily translated to other languages):
def maximumSumOfAdjacentProducts(n):
if n == 1: # special case needed for a one element sequence
return 1
sumOfProducts = n * (n-1) # this pair is the "center" of the sequence
for i in range(n-2, 0, -1): # iterate downward from n-2 to 1
sumOfProducts += i*(i+2) # each adjacent pair is separated by 2
return sumOfProducts
Sort the array, call it sortedArray in ascending order.
Remove max1, max2 and put them in a result list.
Remove the next element and add it to the side of MAX(max1, max2).
Update max1 and max2. i.e. max1 is left side and max2 is right side of the list.
Repeat steps 3 & 4 until the sorted input array has elements.
Example:
inputArray: 1,3,4,2,5
sortedArray: 1,2,3,4,5
Add 5 and 4 to the list first.
result = [5, 4]
Remove 3 and add it to MAX(5,4)
result = [3, 5, 4]
Remove 2 and add it to MAX(3,4)
result = [3, 5, 4, 2]
Remove 1 and add it to MAX(3,2)
result = [1, 3, 5, 4, 2]

Resources