This question already has answers here:
Find pairs with least difference
(3 answers)
Closed 6 months ago.
Given a list of Integers and a number k. We have to return the k minimum absolute differences between different pairs of Integers in sorted order (ascending)
eg: If the Given list of integers is 6, 9, 1, and k=2 Then the output should be [3,5]
Because the pairwise absolute differences are: |6-9|=3, |6-1|=5, |9-1|=8 the lowest 2 in ascending order will be 3,5
I solved this problem in following ways:
Calculate the pairwise absolute difference-> sort the list -> return the first k elements
Score: 7/15 Only 7 test cases passed out of 15. Rest I got Time Limit Exceeded Error
Instead of sorting I put all the elements in a min heap using the PriorityQueue in Java. The results were similar 8/15
Not sure what could be more efficient way to approach this problems. Any ideas?
Sort the list first
Init d = 1
Then get the absolute difference between elements 'd' distance apart and insert into a min-k heap. Quit as soon as your heap got k elements.
Go to step 3 with d = d + 1
Answer is in your heap. Complexity depends on k. If k ~ n^2, then it could be O(n^2) because you have to find all pairs. But it could be much better if k << n^2.
Related
This question already has answers here:
The Most Efficient Way To Find Top K Frequent Words In A Big Word Sequence
(19 answers)
Closed 8 years ago.
The problem is: Given a list of strings and an integer k, return the top k most frequently occurring words in descending order based on frequency. This must be done O(N) where N is the length of the list of strings.
The popular solution is to store (word, frequency) in a hash table, sort the hash table by frequency, and output the top k words. This is not O(N) however because sorting by frequency takes O(NlgN).
I'm wondering if a O(N) solution actually exists. I've thought about quick-select where you get the kth top most occurring word and sort the remaining frequencies but that would be O(N + klgk) which is still O(NlgN) when k is say N.
Yes, it does exist. There is no need to actually sort the pairs. One can find k-th element in O(n)(it's a well known algorithm). Then all elements that are greater than or equal to the k-th element are the top elements.
Yes, there is a O(n) solution.
You can change the famous SELECT algorithm which running in complexity of O(n) to your needs
(the algorithm purpose is to find the K'th smallest elements out of N elements).
and later you just pick the the elements which are "greater or equal" to the element the algorithm returns.
more details you can find at : SELECT algorithm
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.
I have to write a quicksort algorithm that uses the median of the array as the pivot. From my general understanding from what I read in a book, I have to use a select algorithm in which I split the array into n/5 sub arrays, sort each of the sub arrays using insertion sort, find the median, then recursively call the select algorithm to find the median of the medians. I'm not even sure how to start this and I'm pretty confused. the selectMedian algorithm call is supposed to look something like this: SelectMedian(int first, int last, int i) where i is the ith index I want to select (in this case it would be the middle index, so array.length/2). The book I'm reading gives this description of it:
The algorithm in words (if n>1):
1. Divide n elements into groups of 5
2. Find median of each group (use insertion sort for this)
3. Use Select() recursively to find median x of the n/5
medians
4. Partition the n elements around x. Let k = rank(x)
5. if (i == k) then return x
if (i < k) then use Select() recursively to find i-th
smallest element in first partition else (i > k) use
Select() recursively to find (i-k)th smallest element in
last partition.
can anyone assist me in writing this algorithm? thanks!
Would that really be necessary? Why not use the median of three where you select the pivot based on the median of three values, ie. the first, middle and last values.
Or you could even use a random pivot, which will drastically lower the chances of ending up with QuickSort's worst case time of O(N²), which may also be appropriate for your implementation.
I assume you can figure out created n/5 sub-arrays of 5 elements each.
Finding the median of a subarray is fairly easy: you look at each element and find the element which has two smaller elements.
For example, you have 1 4 2 3 5. 1 has no smaller elements. 4 has three smaller elements. 2 has one smaller element. 3 has two smaller elements; this is the one you want.
Now you have found n/5 medians. You want to find the median of the medians, so you run the algorithm again.
Example:
1 7 2 4 9 0 3 8 5 6 1 4 7 2 3
[1 7 2 4 9][0 3 8 5 6][1 4 7 2 3]
findMedian([1 7 2 4 9]) = 4;
findMedian([0 3 8 5 6]) = 5;
findMedian([1 4 7 2 3]) = 3;
[4 5 3]
findMedian([4 5 3]) = 4;
4 is your pivot.
The reason you do this is to try and split your array evenly; if your array is split lopsided, you'll get O(N^2) performance; if your array is split evenly, you get O(NlogN) performance.
Selecting a random pivot means you could get either one - in practice it would balance out to O(NlogN) but a lot of applications want consistent performance, and random quicksort is not consistent from run to run.
The reason we use 5 (instead of 3 or 7) is because we're adding another term of time complexity searching for the median - this term has to be less than O(NlogN) but you want it to be as small as possible. Using 3 gets you O(N^2), using 5 gets you O(NlogN), and 5 is the smallest number for which this is true.
(the algorithm to find the median in linear time was given by Blum, Floyd, Pratt, Rivest and Tarjan in their 1973 paper "Time bounds for selection", and answered a famous open problem)
QUICKSORT2(A, p, r)
if p<r
median=floor((p + r) /2) - p + 1
q=SELECT(A, p, r, median)
q=PARTITION2(A, p, r, q)
QUICKSORT2(A, p, q-1)
QUICKSORT2(A, q+1, r)
PARTITION2(A, p, r, q)
switch between A[r] and A[q]
return PARTITION(A, p, r)
Given a set of integers, how to find a subset that sums to a given value...the subset problem ?
Example : S = {1,2,4,3,2,5} and n= 7
Finding the possible subsets whose sum is n.
I tried to google out found many links,but were not clear.
How can we solve this in java and what is the data structure to be used and its complexity ?
In three steps:
Find the powerset of S (the set of all subsets of S)
Compute the sum of each subset
Filter out subsets that did not sum to 7.
I wont give you any code, but explain how it works.
Run a loop from 0 to (2^k-1)
For each value in 1, a 1 in its binary representation indicates that this value is chosen and 0 otherwise.
Test to see if the sum of chosen numbers is equal to n.
The above method will evaluate each possible subset of the given set.
If the upper limit of the values is small, then Dynamic Programming Approach could be used.
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.