从数组中找到对(2个元素),其数组必须大于给定的整数

时间:2018-04-11 05:35:15

标签: java arrays algorithm

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

约束:您无法操纵数组,意味着任何排序或制作原件的副本,然后排序或更改值会受到限制。

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

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

我的解决方案: 第一个是使用O(N^2)的Brute-Force,并尝试获取该对的产品并进行检查。现在我将其即兴创作于以下逻辑

假设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 我们可以在任何新的数据结构中存储最少数量的条目,但它应该是最小值,而不是该数据结构中原始或太多元素的完整副本

1 个答案:

答案 0 :(得分:2)

我们假设我们有:

Map<String, Object> props = new HashMap<>();
         props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, 
("xxx.xx.xxx.xxx:9092");
         props.put(ConsumerConfig.GROUP_ID_CONFIG, "ept-oi-log");
         props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
         props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "15000");
         props.put(ConsumerConfig.CLIENT_ID_CONFIG, "1");
         props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, 
IntegerDeserializer.class);

props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, 
StringDeserializer.class); 

DefaultKafkaProducerFactory<Integer, String> producer = new 
DefaultKafkaProducerFactory<>( producerConfigs(props));

KafkaTemplate<Integer, String> openInterfacesSubscriber = new KafkaTemplate<> 
(producer); 

for (all in { "AGENTBYACCOUNTMEASURES", "AGENTBYROUTINGSERVICEMEASURES") {

String subRequest = String.format("   {\"userName\":\"%s\",\"password\":\"%s\",\"subscriptionRequestId\":\"5d09vjfgk\",\"request\":\"SUBSCRIBE\", \"measuresStream\":\"% s\",\"version\":\"3.4\"}", "MikeGrey@odl.lab",  "Avaya123", measureName); 

// THERE IS NO KAFKA SECURITY HERE: USERNAME/PWD ABOVE IS FOR THE subRequest
// STRING ONLY, ANYONE CAN CONNECT TO THIS KAKFA INSTANCE.

openInterfacesSubscriber.send("realtimesubscriptionrequest", 0, i++, subRequest);

天真的暴力实施是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); } O(n)的额外空间。我认为只跟踪已遇到的数字就足够了。如果我们再次遇到某个数字 ,则表示它已经被处理为seenNumbers,这意味着已经生成了具有此数字的所有可能对。

我再次决定&#34;&#34;&#34;&#34;您建议的解决方案。因为它非常棘手。您不能只是values[i]并将其用作权利的最小值。您需要考虑k/values[i] + 1以及否定values[i]==0。并不是说它不可能,但它非常麻烦,而且很容易犯错误。我可能在采访中提到这一点,但不是这样做。简单的乘法更容易。

但即使使用简单的乘法,您也必须考虑整数溢出。因此values[i]。这通常是对采访的追赶,谷歌喜欢它。 :)