您好我正试图从IEEEXtreme 2014解决这个问题:
您将获得循环排列的N个整数。存在N种方式来选择长度为M(M 我的方法是首先创建一个排序数组列表,将新输入插入正确的位置。我将前M个整数添加到列表中。记录第K个最小值。然后我继续删除最旧的整数并将下一个整数添加到列表中,并将新的第K个值与旧的值进行比较。这是我的排序数组列表。 我认为这种蛮力方法效率不高,但还不能提出任何想法。你知道更好的解决方案吗?感谢。class SortedArrayList extends ArrayList {
public void insertSorted(int value) {
for (int i = size()-1; i >= 0; i--){
if( value - (Integer)get(i)>=0){
add(i+1,new Integer(value));
return;
}
}
add(0,new Integer(value));
}
}
答案 0 :(得分:1)
这是一个更有效的解决方案:
让我们摆脱循环,让事情更简单。我们可以通过将给定的数组附加到自身来实现。
我们可以假设输入中的所有数字都是唯一的。如果不是这种情况,我们可能会使用一对(element, position)
而不是每个元素。
让我们对给定的数组进行排序。现在我们将在答案上使用二进制搜索(即,排序全局数组中所有子数组中k
个最小元素的位置)。
如何检查固定候选x
是否至少与k-th
最小数字一样大?让我们用x
标记小于或等于1
的数字的所有位置,其余用0
标记。现在我们只需要检查是否存在长度为M
的子数组,其中至少包含k
个子数据。我们可以使用滚动总和在线性时间内完成。
时间复杂度为:O(N log N)
用于对输入进行排序+ O(N log N)
以便在答案上进行二进制搜索(有O(log N)
个检查,并且每个检查都按线性时间完成,如4)。因此,总时间复杂度为O(N log N)
。
P.S。我可以想到其他几个具有相同时间复杂度的解决方案,但这个解决方案似乎是最简单的(它不需要任何自定义数据结构)。
答案 1 :(得分:0)
圆形阵列问题的更优雅的解决方案是简单地使用模数。所以,如果您只是在寻找模拟圆形阵列的解决方案,我会建议这样的事情:
int n = somevalue;//the startingpoint of the subsequence
int m = someothervalue;//the index in the subsequence
int absolute_index = (n + m) % N;
其中N是序列中元素的总数。
提高效率的下一步是存储第k个值的索引。这样,您只需每M步计算一个新的K值(最差情况),并将其与每个其他步骤的一个新值进行比较。 但我会把它留给你;)