题目: https://leetcode.com/problems/move-zeroes/
开始自己实现了一个,但需要 20ms ,只能 beats 27.02%。
然后去论坛中看了好几个实现,有些号称能 beats 95% , 但我照着实现、提交后仍然只能 20ms , beats 27.02%。
论坛中的实现、我的实现都和编辑推荐的算法一样。
语言选的是 C++ 。
附我的实现:
class Solution
{
public:
void moveZeroes(vector<int>& nums)
{
int i = 0;
int l = nums.size();
while (nums[i] != 0 && i < l) ++i;
for (int j = i + 1; j < l; ++j)
{
if (nums[j] != 0)
{
nums[i++] = nums[j];
}
}
while(i < l) nums[i++] = 0;
}
};
1
yongzhong 2016-07-21 19:21:53 +08:00
号称 95 的一般都是很早以前提交的,其他人拿他的答案刷一刷,比率就降下来了
|
3
breeswish 2016-07-21 22:34:32 +08:00 1
算法不复杂,所以时间太短,不稳定因素比较多导致测量不准确
不信你多交几遍同样的代码,可能就某次刷到前 10%了 |
4
mengzhuo 2016-07-22 00:20:33 +08:00
呃……为啥你有三个循环
明明一个就成了啊 |
5
Valyrian 2016-07-22 05:43:01 +08:00 1
20ms...
这点时间能说明啥。。误差都比这个长 |
6
yaoyuan7571 2016-07-22 10:18:03 +08:00 1
void moveZeroes(vector<int>& nums) {
int zero_count=0; for (int i=0; i<nums.size(); i++) { if (nums[i] == 0) { zero_count++; } else { int j=i-zero_count; nums[j] = nums[i]; } } int last = nums.size()-1; for (int i=0;i<zero_count;i++) { nums[last]=0; last--; } } |
7
soli OP |
8
flyingghost 2016-07-22 12:12:08 +08:00
哪里参加 beat ?
我执行时间是 0ms 。 ```java public class Solution { public void moveZeroes(int[] nums) { int empty=0; int start=0; for(int i=0;i<nums.length;i++){ if(nums[i]==0){ empty++; } else{ if(empty==0){ start=i+1; } else{ nums[start]=nums[i]; nums[i]=0; start++; } } } } } ``` |
9
flyingghost 2016-07-22 12:14:43 +08:00
。。。不是说好了支持 markdown 的吗?
|
10
soli OP |
11
soli OP @flyingghost 说来奇怪,很多这种算法题,用 Java 反而测出来的性能更高。
Java > C++ > C 。。。很无语 提交之后去看『 Submission Details 』,那里有个图表可以看到 beats ,还可以在各种语言之间比较。 |
12
soli OP @breeswish 我擦!真坑啊!果然是误差!
我连续提交了几次相同的代码,每次结果都不一样!终于有一次刷到了 16 ms beats 94.91%! 我又刷了一次上面那位仁兄 @yaoyuan7571 的代码,时间也变了,变成 22ms beats 22.41% 了。 郁闷了好几天,深深地了怀疑自己的智商。。。 |
13
soli OP |
15
mengzhuo 2016-07-22 13:56:26 +08:00 via iPhone
而且都是 O(n)怎么可能有这么大差异?
|
16
lawlietxxl 2016-07-22 14:04:12 +08:00
12 行 solution
public class Solution { public void moveZeroes(int[] nums) { if(nums.length < 2) return; int idx = 0; for(int n:nums) if(n != 0) nums[idx++] = n; while(idx < nums.length) nums[idx++] = 0; } } |
17
fcicq 2016-07-22 14:06:37 +08:00
online judge 也就会用 time 计数. perf 等方法他们不会. 误差太正常.
|
18
pathletboy 2016-07-22 14:43:02 +08:00 1
懒汉版
class Solution { public: static int compvar(const void *one, const void *two) { return *(int*)one==0; } void moveZeroes(vector<int>& nums) { qsort(&nums[0], nums.size(), sizeof(int), compvar); } }; |
19
YORYOR 2016-07-22 18:00:50 +08:00
|
20
YORYOR 2016-07-22 18:01:48 +08:00
java 这竞争。。
|
21
SuperFashi 2016-07-22 18:52:34 +08:00 via Android
这误差就是评测机的玄学,像我们这种打 oi 的就得祈祷评测机不出差错,上次写了个博弈论的记忆化搜索,基本上都在 960-990ms 之间,我运气差,交了好几遍都是 1.006s ,一怒之下刷了 5 次,终于不 tle 了。
而且 leetcode 上 java 比 c++快,不高兴。 但是我想吐槽一下两位: @yaoyuan7571 为啥不用迭代器呢…… @pathletboy ……为啥要用 c 的 qsort 和排序函数写法, c++本来就是为了避免各种指针的使用的啊…… |
22
DaCong 2016-07-22 20:22:37 +08:00
@flyingghost 评论不支持 markdown ,只有帖子正文支持
|
23
yhylord 2016-07-22 20:43:58 +08:00
@SuperFashi 确实 C++11 的话写迭代器用 auto 就行了巨爽,但是更早的要手动写长长的 vector<int>::iterator 还是挺烦的
|
24
skydiver 2016-07-22 22:55:11 +08:00
class Solution {
public: void moveZeroes(std::vector<int> &nums) { std::stable_partition(nums.begin(), nums.end(), [](int a) { return a != 0;}); } }; 最简单的写法……可惜还是 20ms |
25
jeffersonpig 2016-07-23 18:10:43 +08:00
leetcode 的性能数据没个准头的
|
26
breeswish 2016-07-24 15:41:10 +08:00
@soli 这个其实没法儿准确测量,撞上时间片调度一下就 10ms 加上去了…
以及各种 OJ 目标并不是准确测量耗时,而是衡量你编写算法的对错,因而只测「答案是否正确」、「是否在指定时间内结束(即算法时间复杂度是否满足需求)」、「资源占用是否在指定空间内(空间复杂度是否满足需求)」,是不会多次运行测量准确时间的,这没意义。 |
27
soli OP |
28
laobubu 2016-09-21 21:20:27 +08:00
https://ooo.0o0.ooo/2016/09/21/57e288f2d12d3.png
虽然是 C++,但是还是用 C 的方式写了一个,突然感觉碉堡了…… |