【问题标题】:Find the pairs (2 Elements) from an array whose product must be greater then given Integer从乘积必须大于给定整数的数组中找到对(2 个元素)
【发布时间】:2018-04-11 05:35:15
【问题描述】:

我在一次采访中得到了这个问题。 假设您有一个 未排序的整数 数组,其可能值为正、负和零。您还有一个变量k,其中包含一个整数。现在找到乘积大于k 的一对或多对,非重复的,如果存在的话。 k 可以是任何值,+ve、-ve 或零

约束:您不能操作数组,这意味着任何排序或复制原始数据,然后排序或更改值都会受到限制。

如果可能的话,它应该低于 O(n^2) 时间复杂度和最小空间(没有明确提到空间,但他们说尽可能使用最低)

例如:给定Array [0,-1, 5, 45, 4, 1, -3]k = 20 我的解决方案是在面试时给出的:

我的解决方案: 第一个是蛮力使用O(N^2) 并试图获取该对的产品并进行检查。现在我即兴创作了以下逻辑

假设k = 40,我得到array[i] = 2。现在int divide = k/array[i]divide+ = 1。如果我遇到任何数字说array[j] > dividearray[j] < k,那么int product = array[i] * array[j] 的乘积将是product > k

逻辑: 如果我有一个数字 1000 并且我得到了 array[i] = 3 的某个值 i。如果我得到n = 1000 / array[i] 并增加n = n+1,并且如果n 存在于数组中,则n * array[i] > 1000 的乘积

编辑:+ve 表示正,-ve 表示负,并找到所有对,而不是在第一对停止。 编辑 2 我们可以在任何新的数据结构中存储最少数量的条目,但它应该是最小的,而不是原始的完整副本或该数据结构中的元素过多

【问题讨论】:

    标签: java arrays algorithm


    【解决方案1】:

    假设我们有:

    int[] values;
    int k;
    // Found pairs will be fed to this consumer
    BiConsumer<Integer, Integer> results;
    

    天真的蛮力实现是O(n^2)。问题是,是否有可能让它变得更好。我个人不这么认为。在最坏的情况下,数组的所有元素都可以形成对。例如,如果数组包含不同的正整数和k=0。即使您对数组进行排序,您仍然需要实际生成对。这意味着蛮力实际上已经足够了。

    现在讨论空间复杂度。问题是您需要生成 非重复 对。因此,您需要跟踪您已经看过哪些对,哪些没有。天真地是O(n^2),但我认为这可以简化为O(n)

    下面是代码草图:

    Set<Integer> seenNumbers = new HashSet<>();
    for (int i = 0; i < values.length - 1; i++) {
        int left = values[i];
    
        if (seenNumbers.contains(right)) {
            continue;
        }
    
        for (int j = i + 1; j < values.length; j++) {
            int right = values[j];
    
            if (seenNumbers.contains(right)) {
                continue;
            }
    
            if (((long)left*(long)right) > k) {
                results.accept(left, right);
                if (left != right) {
                    results.accept(right, left);
                }
            }
        }
        seenNumbers.add(left);
    }
    

    此代码为seenNumbers 使用了O(n) 的额外空间。我认为只跟踪已经遇到的数字就足够了。如果我们再次遇到某个数字,这意味着它已经被处理为values[i],这意味着已经生成了具有该数字的所有可能对。

    我再次选择了您建议的“除法”解决方案。因为它相当棘手。您不能只使用k/values[i] + 1 并将其用作权利的最低要求。您需要考虑values[i]==0 以及负values[i]。并不是说不可能,而是非常麻烦而且极易出错。我可能会在采访中提到这一点,但不会这样做。简单的乘法要容易得多。

    但即使使用简单的乘法,您也必须考虑整数溢出。为此(long)left*(long)right。这通常是面试中的一个陷阱,谷歌喜欢它。 :)

    【讨论】:

    • 我刚刚注意到,如果values[i]==values[j],此解决方案将跳过(values[i], values[j]) 解决方案。
    猜你喜欢
    • 2021-05-09
    • 2015-11-18
    • 2019-10-24
    • 1970-01-01
    • 2017-02-02
    • 2017-01-08
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多