The best solution (considering time complexity) for the function implementation - algorithm

A function does the following task:
For example L = [[1, 2, 3], [1, 2], [1, 2, 3, 5, 6, 8], [1, 8, 6, 10, 21], [1, 4, 6, 9], [22]]; (array of arrays)
find out the index number of L such that all digit numbers in the value(sub-array) don't appear in other sub-arrays. In this example, the function would return 5 (the index of [22]) because 22 is only in this sub-array.
What could be the optimal solution in time complexity

The algorithm is to keep track of all the numbers you've seen so far (for example in a hashset), and process the sub-arrays one by one until you find one which matches your condition. In the worst case it's O(n) basic set operations, where n is the sum of the lengths of the subarrays of L. This is O(n) comparisons on average if you use a hashset.

Related

Minimize the difference of the distance between points on the line

My problem is as follows:
Given n points on a line segment and a threshold k, pick the points on the line so that would minimize the average difference of the distance between each consecutive point and the threshold.
For example:
If we were given an array of points n = [0, 2, 5, 6, 8, 9], k = 3
Output: [0, 2, 6, 9]
Explanation: when we choose this path, the difference from the threshold in each interval is [1, 1, 0] which gets an average of .66 difference.
If I chose [0, 2, 5, 8, 9], the differences would be [1, 0, 0, 2], which averages to .75.
I understand enough dynamic programming to consider several solutions including memorization and depth-first search, but I was hoping someone could offer a specific algorithm with the best efficiency.

What is the most efficient way to split an array of numbers, such that sum of each subset is as close to a target as possible, without exceeding it?

I am faced with this optimization challenge:
Take for example the array, [1, 2, 4, 3, 3, 6, 2, 1, 6, 7, 4, 2]
I want to split this into multiple sub-arrays, such that their sums are as close to a target sum. Say, 7.
The only condition I have is the sums cannot be more that the target sum.
Using a greedy approach, I can split them as
[1, 2, 4], [3, 3, 1], [6], [2, 4], [6], [7], [2]
The subset sums are 7, 7, 6, 6, 6, 7 and 2.
Another approach I tried is as follows:
Sort the array, in reverse.
Set up a running total initialized to 0, and an empty subset.
If the list is empty, proceed to Step 6.
Going down the list, pick the first number, which when added to the running total does not exceed the target sum. If no such element is found, proceed to Step 6, else proceed to Step 5.
Remove this element from the list, add it to the subset, and update running total. Repeat from step 3.
Print the current subset, clear the running total and subset. If the list isn't empty, repeat from Step 3. Else proceed to Step 7.
You're done!
This approach produced the following split:
[7], [6, 1], [6, 1], [4, 3], [4, 3], [2, 2, 2]
The subset sum was much more even: 7, 7, 7, 7, 7 and 6.
Is this the best strategy?
Any help is greatly appreciated!
I think you should use the terms "subset" and "sub-array" carefully. What you are looking for is "subset".
The best strategy here would be to write the recursive solution that tries each possibility of forming a subset so that the sum remains <= maximum allowed sum.
If you carefully understand what the recursion does, you'll understand that some sub-problems are being solved again and again. So, you can (memoize) store the solutions to the sub-problems and re-use them. Thus, reading about dynamic programming will help you.

Partition an array into subsets of fixed size with minimum sum difference

I have found versions of this problem for either 2 subsets of half the size of the original array or with any number of subsets of any length. Does anybody have any pointers to any good solution for this problem? (can be greedy)
Given an array of positive numbers of length N (can have repetitions)
Partition the N numbers into subsets of length M with their sum difference minimized.
Simple example:
N=9, M=2
[5, 2, 3, 7, 5, 3, 7, 8, 1]
into
[[8, 1], [7, 2], [7, 3], [5, 5]] + [3] (leftover)
9 9 10 10
My real world use case is to group files of different sizes into batches of a given length but having the total size of each batch be as close as possible to that of the other batches.
Thanks!

Place Intervals to Maximize Number of Adjacency

My problem:
I have n "items" to place on an integer axis. Each item contains several choices of placement, represented as closed intervals of integers. These intervals can have some overlapping elements. The goal is to find a non-overlapping placement (if any) of the n items on the int axis with maximal number of interval adjacency.
More details with the terms used above:
1) Overlapping: interval [1, 4] and [3, 6] have two overlapping elements {3} and {4}; interval [2, 5] and [6, 10] do not overlap.
2) Interval adjacency: interval [a, b] and [b+1, c] are called adjacent. The number of interval adjacency for this example is 1. The maximal possible number of interval adjacency for n items is n-1, which occurs when the placement makes n intervals pair-wisely adjacent.
Example:
There are 3 items; their placement choices are listed here
item1 has 2 choices: [1, 4], [2, 5]
item2 has 3 choices: [5, 8], [9, 11], [16, 18]
item3 has 2 choices: [3, 5], [13, 15]
One feasible placement is
[1, 4](item1), [5, 8](item2), [13, 15](item3)
Another two feasible placement are
[1, 4](item1), [16, 18](item2), [13, 15](item3); and
[2, 5](item1), [16, 18](item2), [13, 15](item3).
All these three placement in this example are optimal. The number of interval adjacency is 1.
My question:
Is there a better way than enumeration of all possibilities?
I can only think of that if an interval choice of an item overlaps with all the choices of another item, then this choice can be excluded. Any ideas are welcome:)

Find the middle element in merged arrays in O(logn)

We have two sorted arrays of the same size n. Let's call the array a and b.
How to find the middle element in an sorted array merged by a and b?
Example:
n = 4
a = [1, 2, 3, 4]
b = [3, 4, 5, 6]
merged = [1, 2, 3, 3, 4, 4, 5, 6]
mid_element = merged[(0 + merged.length - 1) / 2] = merged[3] = 3
More complicated cases:
Case 1:
a = [1, 2, 3, 4]
b = [3, 4, 5, 6]
Case 2:
a = [1, 2, 3, 4, 8]
b = [3, 4, 5, 6, 7]
Case 3:
a = [1, 2, 3, 4, 8]
b = [0, 4, 5, 6, 7]
Case 4:
a = [1, 3, 5, 7]
b = [2, 4, 6, 8]
Time required: O(log n). Any ideas?
Look at the middle of both the arrays. Let's say one value is smaller and the other is bigger.
Discard the lower half of the array with the smaller value. Discard the upper half of the array with the higher value. Now we are left with half of what we started with.
Rinse and repeat until only one element is left in each array. Return the smaller of those two.
If the two middle values are the same, then pick arbitrarily.
Credits: Bill Li's blog
Quite interesting task. I'm not sure about O(logn), but solution O((logn)^2) is obvious for me.
If you know position of some element in first array then you can find how many elements are smaller in both arrays then this value (you know already how many smaller elements are in first array and you can find count of smaller elements in second array using binary search - so just sum up this two numbers). So if you know that number of smaller elements in both arrays is less than N, you should look in to the upper half in first array, otherwise you should move to the lower half. So you will get general binary search with internal binary search. Overall complexity will be O((logn)^2)
Note: if you will not find median in first array then start initial search in the second array. This will not have impact on complexity
So, having
n = 4 and a = [1, 2, 3, 4] and b = [3, 4, 5, 6]
You know the k-th position in result array in advance based on n, which is equal to n.
The result n-th element could be in first array or second.
Let's first assume that element is in first array then
do binary search taking middle element from [l,r], at the beginning l = 0, r = 3;
So taking middle element you know how many elements in the same array smaller, which is middle - 1.
Knowing that middle-1 element is less and knowing you need n-th element you may have [n - (middle-1)]th element from second array to be smaller, greater. If that's greater and previos element is smaller that it's what you need, if it's greater and previous is also greater we need to L = middle, if it's smaller r = middle.
Than do the same for the second array in case you did not find solution for first.
In total log(n) + log(n)

Resources