Java 求差为k的数组中的对数的最佳方法

Java 求差为k的数组中的对数的最佳方法,java,algorithm,search,optimization,Java,Algorithm,Search,Optimization,我在hackerrank上解决问题。我有两种想法: 输入:未排序数组(a)和k 第一种方法: static int pairs(int[] a,int k) { /* Complete this function */ int temp; int len=a.length; int count=0; Arrays.sort(a); for(int i=0;i<len;i++){ temp=a[i]; for(int j=i

我在hackerrank上解决问题。我有两种想法:

输入:未排序数组(a)和k

第一种方法:

static int pairs(int[] a,int k) {
  /* Complete this function */
    int temp;
    int len=a.length;
    int count=0;
    Arrays.sort(a);
    for(int i=0;i<len;i++){
    temp=a[i];
        for(int j=i+1;j<len;j++){
            if(temp-a[j]==-k){
                count++;
                break;
            }
        }
    }
    return count;
}
1) 对数组进行排序

2) 对于每个数组元素a[i],使用二进制搜索查找元素a[i]+K。如果找到,则增加计数并中断内部循环

第二种方法:

static int pairs(int[] a,int k) {
  /* Complete this function */
    int temp;
    int len=a.length;
    int count=0;
    Arrays.sort(a);
    for(int i=0;i<len;i++){
    temp=a[i];
        for(int j=i+1;j<len;j++){
            if(temp-a[j]==-k){
                count++;
                break;
            }
        }
    }
    return count;
}
1) 对数组进行排序

2) 对于每个数组元素a[i],使用linearsearch查找元素a[i]+K。如果找到,则增加计数并中断内部循环

我发现第一种方法更好,因为它可以解决n(logn)中的问题。但是,当解决方案上有多个测试用例时,方法2花费的时间更少。有人能解释一下原因吗

以下是两种方法的代码:

第一进近代码:

static int pairs(int[] a,int k) {
  /* Complete this function */
    int temp;
    int len=a.length;
    int count=0;
    int beg;
    int mid;
    int end;
    int midVal;
    Arrays.sort(a);
    for(int i=0;i<len-1;i++){
    temp=a[i]+k;
    beg=i+1;  
    end=len-1;
        for(int l=beg;l<len;l++){
            mid=(beg+end)/2;
            midVal=a[mid];
            if(midVal==temp){
                count++;
                break;
            }
            else if(midVal>temp){
                end=mid-1;
            }
            else{
                beg=mid+1;
            }
        }

    }
    return count;
}
静态int对(int[]a,int k){
/*完成此功能*/
内部温度;
int len=a.长度;
整数计数=0;
int beg;
int mid;
内端;
中段内;
数组。排序(a);

对于第1个代码中的(int i=0;i,您的内部循环终止条件不正确。如果
beg
end
指针相互交叉,它应该终止


将其更改为
while(beg在这两种方法中,第一种方法是最好的,但有比这两种方法更好的方法:-

下面是一个更好方法的伪代码:-

for(i=0;i<Arr.length;i++) {
  Hashmap.add(Arr[i])
}
count=0;
for(j=0;j<Arr.length;j++) {

  if(Hashmap.containsKey(Arr[j]+k))
     count++;

}

for(i=0;i您也可以使用set无需使用hashmap

public static void main(String[] args) throws Exception {

    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

    int[] firstLine = Stream.of(in.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    int count = firstLine[0];
    int diff = firstLine[1];           
    Set<Integer> numbers = new HashSet<Integer>(Stream.of(in.readLine().split(" ")).map(Integer::valueOf).collect(Collectors.toList()));

    int pairCount = 0;
    for (Integer number : numbers) {
        pairCount += (numbers.contains(number+diff) ? 1:0); 
    }
    System.out.println(pairCount);                
}
publicstaticvoidmain(字符串[]args)引发异常{
BufferedReader in=新的BufferedReader(新的InputStreamReader(System.in));
int[]firstLine=Stream.of(in.readLine().split(“”).mapToInt(Integer::parseInt).toArray();
整数计数=第一行[0];
int diff=第一线[1];
Set number=newhashset(Stream.of(in.readLine().split(“”).map(Integer::valueOf).collect(Collectors.toList());
int pairCount=0;
for(整数:数字){
pairCount+=(数字。包含(数字+差异)?1:0;
}
系统输出打印项次(对计数);
}
私有静态int CountDistinctPairs(int[]nums,int k){
//TODO自动生成的方法存根
HashMap=newHashMap();
HashSet=newhashset();
对于(int i=0;i静态布尔校验重复思想(int-arr[],int-k)
{
//创建一个空哈希集
HashSet=newhashset();
//遍历输入数组
对于(int i=0;i=k)
设置。移除(arr[i-k]);
}
返回false;
}
公共静态void main(字符串[]args)
{
int arr[]={10,5,3,4,3,5,6};
如果(检查并思考(arr,3))
System.out.println(“是”);
其他的
系统输出打印项次(“否”);
}
我的解决方案

System.out.println(“findPair:+findPair(新int[]{4,7,1,2,5,3,0,7,8,5,2},3))

公共静态int findPair(int[]nums,int target){
数组。排序(nums);
整数计数=0;
字符串pairText=“”;
对于(int i=0;i
Duplicate:在第二种情况下,这是最好的方法,虽然排序实际上无助于降低算法的顺序,但如果k值很小,它可能有助于减少线性扫描中的大量开销。当然,最坏的情况是,两者的执行相同。@Sushant根据您的逻辑,如果差异很大,会发生什么@AbhishekBansal:如果我不使用方法2的排序,那么我需要搜索temp-a[j]==-k和temp-a[j]==k,所以对于这个方法,时间复杂度或多或少是O(n^2)。而如果我先对数组排序,则多个测试用例的运行时间会更短。@user3026672如果您进行线性搜索,则无论数组是否排序,每个测试用例的时间复杂度都应为O(n^2)。@AbhishekBansal:感谢abhishek的回复:)这是一个很好的方法。您还应该提到,如果内存不是问题,这是一个更好的方法,因为它必然需要O(n)个额外的空间,而其他解决方案可以在适当的位置实施。@阿披实U是对的,我总是进行空间复杂性分析,但这次没有进行。检查我的编辑。没有添加()在里面HashMap@Kode是的,这就是我指定它为伪代码的原因。您好,k可以是0。您的解决方案在这种情况下不起作用。您可以对此代码添加一些解释吗?以改进您的答案并帮助未来的读者
static boolean checkDuplicatesWithinK(int arr[], int k)
    {
        // Creates an empty hashset
        HashSet<Integer> set = new HashSet<>();

        // Traverse the input array
        for (int i=0; i<arr.length; i++)
        {
            // If already present n hash, then we found 
            // a duplicate within k distance
            if (set.contains(arr[i]))
               return true;

            // Add this item to hashset
            set.add(arr[i]);

            // Remove the k+1 distant item
            if (i >= k)
              set.remove(arr[i-k]);
        }
        return false;
    }

public static void main (String[] args)
    {
        int arr[] = {10, 5, 3, 4, 3, 5, 6};
        if (checkDuplicatesWithinK(arr, 3))
           System.out.println("Yes");
        else
           System.out.println("No");
    }
public static int findPair(int[] nums, int target){ 
    Arrays.sort(nums);

    int count = 0;
    String pairText = "";
    for(int i =0; i < nums.length;i++){
        for(int j =i+1; j < nums.length;j++){

            if(nums[j]-nums[i] == target && (!pairText.equals(nums[i]+", "+nums[j]))){

                //System.out.println(nums[i]+", "+nums[j]);
                pairText = nums[i]+", "+nums[j];
                count++;
            }
        }

    }  


    return count;


}