cpp 数组有趣之一
今天刷 leetcode 遇到一个很神奇的问题:给你一个整数数组 nums 和一个整数 k ,请你统计并返回该数组中和为 k 的子数组的个数 ,子数组是数组中元素的连续非空序列。
单看问题本身并不神奇,但是它的题解非常有趣。我把两个题解放在下面,读者不妨猜猜看,哪个题解是官方的能通过的题解。
1 | class Solution {//题解1 |
既然我都说了题解有趣,那想来大家不难猜到,看上去非常冗余繁琐的题解 2 才是最终的正确答案。而题解 1 则会在某个测试用例上超时。题解 2 不仅用了多余的空间,还有额外用来赋值的 O(n) 时间复杂度,但是它依然比题解 1 快。敏锐的读者已经发现了,题解 1 后续操作的是一个不标准变长数组 int arr[n] ,而题解 2 则是 vector<int>& nums 。问题就出在这里,前者是栈上的数组,后者是堆上的一个容器。 vector 的访问是通过内部指针的间接访问,而 int arr[n] 则能做到直接寻址。再加上 cpp 的编译器对原生数组的优化更激进,最终造成了这个结果。真有趣, cpp 不愧是注重性能的语言。
话说回来,我本人还是更推崇第一种写法。在代码的编写中,应减少冗余变量的出现,以及冗余的操作,这既为了可读性,也为了强迫症(或者代码品味)。再加上本来这两者带来的时间上的差距其实并不大,只有有特殊需求或在特定场景的情况下(比如数据爆炸多)才有必要追求题解 2 的写法。但是 leetcode 里超时的测试用例,数组里只有 4 个元素,这点差别就是超时和通过的天堑了,我认为这并不妥。
这道题并不难,可能今天写在这里的内容对于大佬来说也不算什么新颖的东西。就当我新手就是爱记录好了(还有水博客)。最后给大家展示另一种时间复杂度仅为 O(n) 的更优雅的题解(思路详情详见官方题解)。
1 | class Solution |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 SpeechlessPanda!
评论

