【问题标题】:pairs of numbers that have a difference of K差为 K 的数对
【发布时间】:2014-06-20 21:20:12
【问题描述】:

这是我的在线面试问题,我已经提交了答案。但是,由于时间原因,编译终止了,所以我才提交。我能得到你的反馈吗?提前致谢。

问题:

给定 N 个数字,[N

输入格式:

  • 第一行包含 N 和 K(整数)。
  • 第二行包含 N 个集合的数字。确保所有 N 个数字都是不同的。

输出格式:

  • 一个整数表示具有差异 K 的数字对的数量。

示例输入 #00:

5 2
1 5 3 4 2

示例输出 #00:

3

我的代码:

import java.io.*
import java.util.*;

public class DiffNumbers {
    public static void main(String[] args) throws Exception {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line1 = in.readLine();
        String line2 = in.readLine();
        int n = Integer.parseInt(line1.split(" ")[0]);
        int diff = Integer.parseInt(line1.split(" ")[1]);

        Hashtable table = new Hashtable();
        int[] arr = new int[n];

        for(in i=0; i<n; i++) {
            arr[i] = Integer.parseInt(line2.split(" ")[i]);
            table.put(Integer.parseInt(line2.split(" ")[i]));
        }

        int count = 0;

        for(in i=0; i<n; i++) {
            if(table.containsKey(arr[i]+diff) {
                    count++;
            }
        }
        system.out.println(count);
    }
}

【问题讨论】:

  • 您的示例输入与您对输入格式的描述不符
  • @Ben 这不是 O(n^2) 这是 O(n)。
  • 我看不出有什么需要改进的地方,我不确定的一件事是当你打电话给line2.split(" ")[i] 时,它会拆分line2once 还是n times?在代码中它看起来像 n 次,但现在编译器非常聪明。
  • @A4L 感谢您的评论。

标签: java hashmap hashtable


【解决方案1】:

使用 HashMap/Table 需要额外的空间。如果你想避免它,你可以这样做

1) 对数组进行排序

2) 将 outputCount 初始化为 0

3) 设两个指针。 “first”以 0 开头,“Other”指针以 1 开头。

4)

while(arr[other]-arr[first] <requiredDifference)
    other ++;
if(arr[other]-arr[first] == requiredDifference)
    outputCount++;
else  // no match for arr[first]
    first++;

5)

return outputCount;

解释:- 当差异超过 requiredDifference 时,您将停止前进“其他”指针。所以没有匹配 arr[first]。所以先柜台前进。现在对 new arr[first] 执行相同的逻辑。这次您将继续从“其他”的当前位置开始检查,因为数组已排序;较低的数字将不需要匹配。

【讨论】:

  • 感谢您的回复,但时间复杂度似乎超过 O(n)。您有任何将时间复杂度降低到 O(n) 的建议/解决方案吗?
  • 这个命题的时间复杂度是和整数数组排序的时间复杂度绑定的。步骤 2、3 和 5 是不变的。错误定义/缩进的第 4 步是一个循环,将精确执行 N 次恒定时间迭代,因此 O(n)。最有效的基于比较的排序是 O(n*log(n)),但是基数排序(例如假设一个“16 位”基数,所以整数在 2 遍中排序),你得到整个排序在 O (2*n),所以整个事情可以在 O(n) 内完成。
【解决方案2】:
public static void main(String[] args) throws Exception{
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String line1 = in.readLine();
    String line2 = in.readLine();
    int diff = Integer.parseInt(line1.split(" ")[1]);

    Map<Integer, Object> nMap = new HashMap<Integer, Object>();
    Map<Integer, Boolean> uMap = new HashMap<Integer, Boolean>();
    Map<Integer, Boolean> lMap = new HashMap<Integer, Boolean>();

    String[] numbers = line2.split(" ");

    //init maps
    for(String number : numbers){
        Integer intValue = Integer.valueOf(number);
        nMap.put(intValue, new Object());  //original set, N
        uMap.put(intValue + diff, false);  //upper-bound map
        lMap.put(intValue - diff, false);  //lower-bound map
    }

    int count = 0;
    for(Integer nKey : nMap.keySet()){
        //Do if the lower-bound of n exists in N and if n hasn't used as an upper-bound?
        if(nMap.get(nKey - diff) != null && !uMap.get(nKey)){
            count++;
            //Mark the lower-bound as used.
            lMap.put(nKey - diff, true);
        }

        //Do if the upper-bound of n exists in N and if n hasn't used as an lower-bound?
        if(nMap.get(nKey + diff) != null && !lMap.get(nKey)){
            count++;
            //Mark the upper-bound as used.
            uMap.put(nKey + diff, true);
        }
    }

    System.out.println(count);
}

【讨论】:

  • 你应该解释一下你的代码到底做了什么。
  • @SebastianZartner,我的错。我添加了 cmets。
【解决方案3】:

没有太多理由将整数同时存储在数组和哈希表中。我们可以修改您的代码以在单个 for 循环中完成所有工作。

for(int i=0; i<n; i++) {
    int j = Integer.parseInt(line2.split(" ")[i]) //probably not how I would go about this
    table.put(j);
    if(table.containsKey(j+diff)) {
        count++;
    }
    if(table.containsKey(j-diff)) {
        count++;
    }
}

【讨论】:

  • 这不起作用。如果3 不在表中,则将1 插入表中。然后插入5检查7等等。在此示例中,您的结果将是 2
猜你喜欢
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 2018-07-28
  • 2016-10-02
相关资源
最近更新 更多