admin管理员组文章数量:1122832
There is a list of numbers of size n, find the maximum count of the number of pairs such that it follows the below pattern:
2 * minimum(arr[i],arr[j]) <= maximum (arr[i], arr[j]), where [i,j] in range (0 to n)
The selected indices should be unique, it means if an index say 2 is used to form a pair say (2,5), we should not use the same index 2 to form another pair (2,7).
Example:
arr = [2, 5, 7, 6, 9, 8 , 4 , 2] result = 3
Explanation:
Sort input = [2,2,4,5,6,7,8,9]
All possible pairs that can be formed are:
2 can form pairs with [4,5,6,7,8,9]
4 can form pairs with [8,9]
For 5, there is no matching pair that satisfies the condition.We cannot pick the pair (2,4) because if 4 is already used we cannot form new pairs like (4,8) or (4,9)
Finally, we can form 3 maximum counts of pairs using distinct indices, One such possible pairs are (2,5), (7, 2), and (9, 4), so the answer is 3
Example:
arr = [2,1,2,4,1,4,1] result = 3
Explanation:
Pairs are (2,1), (4,1), and (2,4), so the answer is 3
Constraints:
- n is in the range 1 to n^5
- each input item,is in range 1 to 10^9
I tried solving this using a TreeMap:
import java.util.*;
public class Main
{
public static void main(String[] args) {
System.out.println(solve(Arrays.asList(2, 5, 7, 6, 9, 8 , 4 , 2)));//3
System.out.println(solve(Arrays.asList(2,1,2,4,1,4,1)));//3
}
static int solve(List<Integer> arr) {
arr.sort(Comparator.reverseOrder());
TreeMap<Integer, Integer> map = new TreeMap<>();
for(int e : arr) map.put(e, map.getOrDefault(e,0)+1);
int result = 0;
for(int e : arr) {
int min = 2 * e;
if(map.get(e) == null) continue;
Integer key = map.ceilingKey(min);
if(key != null) {
map.put(e,map.get(e)-1);
if(map.get(e) <=0)map.remove(e);
map.put(key,map.get(key)-1);
if(map.get(key) <=0)map.remove(key);
result++;
}
}
return result;
}
}
But for 2nd test case arr = [2,1,2,4,1,4,1], I am creating pairs in my code as (2,4), (2,4), so it is returning 2 instead of 3.
I tried greedy and 2 pointer approach but both are not working.
What is the correct approach for this problem?
There is a list of numbers of size n, find the maximum count of the number of pairs such that it follows the below pattern:
2 * minimum(arr[i],arr[j]) <= maximum (arr[i], arr[j]), where [i,j] in range (0 to n)
The selected indices should be unique, it means if an index say 2 is used to form a pair say (2,5), we should not use the same index 2 to form another pair (2,7).
Example:
arr = [2, 5, 7, 6, 9, 8 , 4 , 2] result = 3
Explanation:
Sort input = [2,2,4,5,6,7,8,9]
All possible pairs that can be formed are:
2 can form pairs with [4,5,6,7,8,9]
4 can form pairs with [8,9]
For 5, there is no matching pair that satisfies the condition.We cannot pick the pair (2,4) because if 4 is already used we cannot form new pairs like (4,8) or (4,9)
Finally, we can form 3 maximum counts of pairs using distinct indices, One such possible pairs are (2,5), (7, 2), and (9, 4), so the answer is 3
Example:
arr = [2,1,2,4,1,4,1] result = 3
Explanation:
Pairs are (2,1), (4,1), and (2,4), so the answer is 3
Constraints:
- n is in the range 1 to n^5
- each input item,is in range 1 to 10^9
I tried solving this using a TreeMap:
import java.util.*;
public class Main
{
public static void main(String[] args) {
System.out.println(solve(Arrays.asList(2, 5, 7, 6, 9, 8 , 4 , 2)));//3
System.out.println(solve(Arrays.asList(2,1,2,4,1,4,1)));//3
}
static int solve(List<Integer> arr) {
arr.sort(Comparator.reverseOrder());
TreeMap<Integer, Integer> map = new TreeMap<>();
for(int e : arr) map.put(e, map.getOrDefault(e,0)+1);
int result = 0;
for(int e : arr) {
int min = 2 * e;
if(map.get(e) == null) continue;
Integer key = map.ceilingKey(min);
if(key != null) {
map.put(e,map.get(e)-1);
if(map.get(e) <=0)map.remove(e);
map.put(key,map.get(key)-1);
if(map.get(key) <=0)map.remove(key);
result++;
}
}
return result;
}
}
But for 2nd test case arr = [2,1,2,4,1,4,1], I am creating pairs in my code as (2,4), (2,4), so it is returning 2 instead of 3.
I tried greedy and 2 pointer approach but both are not working.
What is the correct approach for this problem?
Share Improve this question edited Nov 26, 2024 at 15:24 CodeCrusader asked Nov 22, 2024 at 21:23 CodeCrusaderCodeCrusader 1551 silver badge10 bronze badges 11 | Show 6 more comments2 Answers
Reset to default 3Lemma 1
If you sort the list first, then there is an optimal solution that divides the list into 2 contiguous parts, a low part and a high part, such that numbers in the low part are only paired with numbers in the high part.
Proof
If an optimal solution does not have such a split, then it has numbers a,b,c,d in order, where a is paired with b and c is paired with d. In this situation, however, b and c can swap partners, so that a pairs with c and b pairs with d. This removes the violation of the splitting constraint involving those two pairs.
Given any optimal solution, we can apply this procedure repeatedly until the list can be split in 2.
Algorithm 1
Now that we know that we can split the list this way, we just have to find an appropriate splitting point. Then we can match elements in a greedy way -- the smallest low element pairs with the lowest possible high element, then the next-lowest, etc.
You can just try all the possible split positions, leading to an O(n2) algorithm.
We can do better than this, though...
Lemma 2
Given a solution divided into 2 parts as above, with P pairs, there is an equivalent solution in which all of the P lowest elements are paired with all of the P highest elements, in order.
This is easily proven with a similar partner-swapping proof.
Algorithm 2
As Kelly Bundy has shown, since there can be at most P=floor(n/2) pairs, the P elements that are paired with higher elements can always fit into the first half of the list, and the P elements paired with lower elements can always fit into the last half.
Therefore, we can just divide the list into halves and greedily match the first half with the second.
That would be an O(n) algorithm, except for the initial sort that makes it O(n log n).
Let's test with the example:
[2,1,2,4,1,4,1]
sort
[1,1,1,2,2,4,4]
P = 3, creating pairs (1,2)
, (1,2)
, (1,4)
Based on Matt's answer: Sort and then greedily try to pair right-half elements with left-half elements. O(n log n) for sorting and O(n) for the rest.
static int solve(List<Integer> arr) {
arr.sort(null);
int i = 0, n = arr.size();
for (int j = (n+1)/2; j < n; j++)
if (2 * arr.get(i) <= arr.get(j))
i++;
return i;
}
Attempt This Online!
本文标签: javaFind unique pairsStack Overflow
版权声明:本文标题:java - Find unique pairs - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736300768a1930937.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
2 * minimum(arr[i],arr[j]) <= maximum (arr[i], arr[j]), where [i,j] in range (0 to n)
. Then why(2,6)
is not part of your first example answer? @CodeCrusader – ArtBindu Commented Nov 23, 2024 at 0:57