我的一位朋友在接受采访时被问到这个问题:
你有两个整数数组(例如{5,6,26,13,2}),阈值 (例如,{19,2,6 3})。你有int K.找到最小的门槛 值>> = K个数据值
我想出了这个伪代码:
int[] data
int[] thresholds
int k
//mergesort lowest to highest
sort(data)//O(nlogn)
sort(thresholds)//O(nlogn)
for(i: 0->thresholds.size-1)//O(n)
if(thresholds[i] >= data[k])
return thresholds[i]
throw exception("no value found that meets condition")
然而,我的朋友(他也提出了类似的解决方案)被告知这个解决方案不是最有效的解决方案(就运行时而言)。我似乎无法找到一个明显比这更好的解决方案
编辑:threshold
中的最小值必须为>=
而非k
数字 值在data
。这意味着必须将输出值与k
的{{1}}个data
不同的索引进行比较。
答案 0 :(得分:1)
这确实不是最佳的。问题等同于在data
数组中找到k最小元素,称为selection problem。如果您有,只需找到大于或等于该值的最小阈值。
median of medians算法在线性时间O(n)和仅有O(1)辅助空间的情况下解决它。 Quickselect具有二次最差情形,但预期线性时间更简单。在C ++中,您可以将std::nth_element
用于具有线性平均大小写的实现。
您还可以使用包含最小 k 元素的堆,同时在数组上滑动。这将花费时间O(n * log k)。
答案 1 :(得分:0)
我想在这里使用Kth Order statistics可能有所帮助。 不需要对阈值或数据进行排序。
对于给定的k,您可以在不排序的情况下获取data[k]
,O(n)
使用selection algorithm
。
现在,您遍历threshold
,查找小于或等于data[k]
的值。那将是O(n)
。