我刚刚试了一个关于codility的测试示例。任务是:“...给定一个由N个整数组成的数组A,返回A中没有出现的最小正整数(大于0)”。
加上:
>
n为[1..10万]范围内的整数;
数组A的每个元素都是[−1,000,000..1,000,000]范围内的整数。
我的第一次尝试是典型的Java 8解决方案:
public int solution(int[] A) {
Set<Integer> l = Arrays
.stream(A)
.boxed()
.filter(i -> i > 0)
.collect(Collectors.toSet());
return IntStream
.iterate(1, a -> a + 1)
.filter(i -> !l.contains(i))
.findFirst()
.getAsInt();
}
所有这些都正确,但中间大小测试数组的测试出现超时。
第二次尝试(朴素的老Java):
public int solution(int[] A) {
boolean[] B = new boolean[1000001];
for (int a : A) {
if (a > 0) {
B[a] = true;
}
}
for (int i = 1; i <= 1000000; i++) {
if (!B[i]) {
return i;
}
}
return 1;
}
这个版本更快,特别是短数组A。
问题:
测试结果第一版:
▶例1第一例测试✔OK 1。0.108s正常
▶例2第二例测试✔OK 1。0.104s正常
▶例3第三例测试✔OK 1。0.104s正常
▶extreme_single单个元素✔OK 1。0.100s正常2。0.104s OK 3。0.104s确定4。0.100s正常
▶简单简单测试✔OK 1。0.100s正常2。0.104s OK 3。0.100s正常
▶extreme_min_max_value最小值和最大值✔OK 1。0.100s正常2。0.104s正常
▶正数_only洗牌序列:0...100然后102...200✔OK 1。0.100s正常2。0.104s正常
▶仅负洗牌序列-100...-1✔OK 1。0.100s正常
▶介质混沌序列长度=10005(带负)超时错误运行时间:0.136秒,时限:0.100秒。1.0.136秒超时错误,运行时间:0.136秒,时限:0.100秒。2.0.128s超时错误,运行时间:0.128秒,时限:0.100秒。3.0.144秒超时错误,运行时间:0.144秒,时限:0.128秒。
▶large_1混沌+序列1,2,...,40000(无负)✔OK 1。0.588s正常
▶large_2洗牌序列1,2,...,100000(无负)✔OK 1。0.748s正常2。0.660s正常
▶大3混沌+多-1,1,2,3(带负)✔OK 1。0.444s正常
测试结果第二版:
▶例1第一例测试✔OK 1。0.004s正常
▶例2第二例测试✔OK 1。0.004s正常
▶例3第三例测试✔OK 1。0.004s正常
▶extreme_single单个元素✔OK 1。0.004s正常2。0.008s正常3。0.004 s确定4。0.008s正常
▶简单简单测试✔OK 1。0.004s正常2。0.004s确定3。0.008s正常
▶extreme_min_max_value最小值和最大值✔OK 1。0.008s正常2。0.004s正常
▶正数_only洗牌序列:0...100然后102...200✔OK 1。0.008s正常2。0.004s正常
▶仅负洗牌序列-100...-1✔OK 1。0.008s正常
▶中混沌序列长度=10005(带负)✔OK 1。0.024秒正常2。0.024秒正常3。0.032s正常
▶large_1混沌+序列1,2,...,40000(无负)✔OK 1。0.220s正常
▶large_2洗牌序列1,2,...,100000(无负)✔OK 1。0.244s确定2。0.244s正常
▶大3混沌+多-1,1,2,3(带负)✔OK 1。0.172s正常
底线:尤其是小尺寸阵列的测试,在Java很普通的情况下,速度要快两个数量级。对于大型数组,它的“仅”因子为3。
编辑:
根据这些评论,我只是试图深入研究这个问题,并尝试:
public int solution(int[] A) {
boolean[] B = new boolean[1000001];
for (int a : A) {
if (a>0){
B[a] = true;
}
}
return IntStream
.iterate(1, a -> a + 1)
.filter(i -> !B[i])
.findFirst()
.getAsInt();
}
结果:
▶例1第一例测试✔OK 1。0.096s正常
▶例2第二例测试✔OK 1。0.096s正常
▶例3第三例测试✔OK 1。0.096s OK折叠所有正确性测试
▶extreme_single单个元素✔OK 1。0.096s确定2。0.096s OK 3。0.096s确定4。0.096s正常
▶简单简单测试✔OK 1。0.100s正常2。0.096s OK 3。0.100s正常
▶extreme_min_max_value最小值和最大值✔OK 1。0.096s确定2。0.100s正常
▶正数_only洗牌序列:0...100然后102...200✔OK 1。0.096s确定2。0.096s正常
▶仅负洗牌序列-100...-1✔OK 1。0.096s OK折叠所有性能测试
▶介质混沌序列长度=10005(带负)超时错误运行时间:0.116秒,时限:0.112秒。1.0.116s超时错误,运行时间:0.116秒,时限:0.112秒。2.0.116s超时错误,运行时间:0.116秒,时限:0.100秒。3.0.124s正常
▶large_1混沌+序列1,2,...,40000(无负)✔OK 1。0.340s正常
▶large_2洗牌序列1,2,...,100000(无负)✔OK 1。0.408s确定2。0.372s正常
▶大3混沌+多-1,1,2,3(带负)✔OK 1。0.272s正常
结论:
编辑2:
实际上,我刚刚找到一篇文章部分描述了这个问题:https://jaxenter.com/java-performance-tutorial-how-fast-are-the-java-8-streams-118830.html。在这篇文章中,作者声称流和在数组上运行的for循环之间的区别是由于流是相当新的事实。然而,这篇文章的日期是4年前。
你没有错过任何东西。装箱整数和检查哈希集比迭代基元数组慢。我对第二种解决方案所做的唯一更改是用一个位集替换boolean[]
,它与boolean[]
类似,但更节省空间,因为每个元素只使用一个位。
问题内容: 我有一个,我想准确复制它。我尽可能地使用实用程序类,但前提是有人花了一些时间来使它正确。因此,自然而然地,我得到了一个包含复制方法的类。 假设我有以下内容: 这失败了,因为基本上它认为不足以容纳。是的,我知道大小为0,但现在应该足够大了,不是吗?如果我必须先填补,那么脑海中就变成了完全没用的功能。因此,除了编写一个复制函数(我现在要做)之外,还有没有适当的方法来做到这一点? 问题答案:
收藏资讯 取消收藏资讯 获取收藏资讯 收藏资讯 POST /news/{news}/collections Response Headers Status: 201 Created 取消收藏资讯 DELETE /news/{news}/collections Response Headers Status: 204 No Content 获取收藏资讯 GET /news/collectio
收藏列表 添加收藏 取消收藏 获取用户收藏的专辑 GET /music/collections Response Status: 200 OK [ { "id": 2, // 专辑id "created_at": "2017-03-15 17:04:31", "updated_at": "2017-06-27 18:40:56", "title": "少女情
收藏 取消收藏 收藏列表 收藏 POST /feeds/:feed/collections Response Status: 201 Created { "message": [ "收藏成功" ] } 取消收藏 DELETE /feeds/:feed/uncollect Response Status: 204 No Centent 收藏列表 GET /feeds/col
在 Favorites(收藏夹)中,您可以储存并管理 Flow 网络服务中您最喜欢的训练目标。在手表上,您可以将您最喜爱的目标用作指定目标。有关更多信息,请参见 Flow 网络服务中的训练规划。 Flow 网络服务中的收藏数量没有限制。如果 Flow 网络服务中收藏夹数量超过 100 个,同步时列表中的前 100 个会传输到手表中。您可以通过拖放操作改变我的最爱的顺序。选择您要移动的“我的最爱”,
在 Favorites(收藏夹)中,可在 Flow 网络服务及 Flow 移动应用中储存并管理您收藏的训练目标。您可以将收藏项目在手表上用作预定目标。有关更多信息,请参见在 Flow 网络服务中规划训练。 您可以看到手表中的数目上限。Flow 网络服务中的收藏项目数量没有限制。如果 Flow 网络服务中收藏项目数量超过 100 个,在同步时,列表中的前 100 个收藏项目会传输到手表中。您可以通过