我正在尝试以a*2 >=b
这样的方式解决数组中的配对数字(a,b)。其中a和b是输入数组中的数字。
示例:
输入:a[] = {1,2,3,4,5}
输出:2
说明:
输入:a[] = {4,3,2,1,5}
输出:2
说明:
输入:a[] = {4,3,2,1,5,6}
输出:3
说明:
我尝试使用如下所示的递归解决问题,但这没有给出正确的结果。任何帮助将不胜感激。
add 1
导致start +1
和end - 1
的结果再次出现(start + 1, end)
,(start, end - 1)
和
(start + 1, end - 1)
想法将a[start]
与数组中的剩余个元素匹配,并获得最大结果。
public static int countPairs(int[] a){
Arrays.sort(a);
return countPairs(a,a.length,0,a.length-1);
}
public static int countPairs(int[] a, int n, int start, int end){
if(end == start){
return 0;
}
if(start >= n || end < 0){
return 0;
}
System.out.print("matching start: "+start + " and end "+end+" ");System.out.println("matching "+a[start] + " and "+a[end]);
if(a[start] < a[end] && a[start] * 2 >= a[end] ){
int res = countPairs(a,n,start+1,end-1) +1;
//System.out.print("inside if matching start: "+start + " and end "+end+" ");System.out.println("matching "+a[start] + " and "+a[end] + " count is "+res);
return res;
}
else{
return max(countPairs(a,n,start+1,end) ,
countPairs(a,n,start,end - 1),countPairs(a,n,start+1,end - 1));
}
}
测试:
import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
public class CountingPairsTest {
static int countPairs(int[] a){
return PairingNumbers.countPairs(a);
}
@Test
public void test1(){
int[] a = {1,2,3,4,5};
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
@Test public void test2(){
int[] a = {1,2,3,4,5,6};
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
@Test public void test5(){
int[] a = {1,2,3,7,4,5,6};
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
@Test public void test6(){
int[] a = {9,8,20,15,21};
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
@Test public void test3(){
int[] a = {5,4,3,2,1};
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
@Test public void test4(){
int[] a = {2,4,5,3,1};
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
@Test public void test7(){
int[] a = new Random().ints(10,1,100).toArray();// IntStream.range(1,100).toArray();
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
@Test public void test8(){
int[] a = new Random().ints(10,1,10).toArray();// IntStream.range(1,100).toArray();
System.out.println("****************************************\n" + Arrays.toString(a));
int count = countPairs(a);
System.out.println("count "+count);
}
}
答案 0 :(得分:8)
我建议答案是a.length / 2
。数组长度的一半(如果长度为奇数,则四舍五入)。您可以按照自己喜欢的任何方式配对数字。对于非负数 a 和 b 如果 a * 2 < b ,只需交换 a 和 b ,您将拥有 a * 2> = b 。因此,由于需要两个数字才能成对,因此您始终可以精确地形成多达数组长度一半的对。
示例(来自注释):[1、2、2、2]。长度为4,长度的一半为2,因此应该有2对。让我们检查一下:(1,2)是一个不错的对,因为1 * 2> =2。(2,2)是另一个不错的对,因为2 * 2> =2。在这种情况下,我们甚至不需要任何交换(在另一方面,相同的配对也可以通过 交换来工作:2 * 2> = 1和2 * 2> = 2)。
如果数组可能包含负数,则它并不总是有效。因此,您可能想要添加一个验证数组的校验,以检查数组是否有效。
您的解决方案出了什么问题?
您的递归算法错误。假设数组为[2,3,7,9]。显然(2,3)和(7,9)是好对,因此这里有两对。由于(2,9)不是有效的配对,因此您描述算法的方式将丢弃2和9中的至少一个,从而没有机会从其余数字中形成两个配对。
答案 1 :(得分:1)
您可以通过以下方式解决它:
i。排序数组。
ii。对于每个数字 a ,找到包含> = 2 * b的数组的最左侧位置 p 。那么您可以计算出满足多少个数字。
复杂度: O(nlogn)+ nlogn