我在面试中得到了这个问题。
假设您有一个未排序的整数数组,其中可能的值为正,负和零。您还有一个变量k
,它包含一个Integer。现在找到一对或多对,非重复的,如果存在,其乘积大于k
。
k
可以是任何内容,+ 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] > divide
和array[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 我们可以在任何新的数据结构中存储最少数量的条目,但它应该是最小值,而不是该数据结构中原始或太多元素的完整副本
答案 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]
。这通常是对采访的追赶,谷歌喜欢它。 :)