我们为什么不能只用O记号来谈论算法?
在刷LeetCode-1TwoSum的時候,有個人在論壇留言,大致意思如下:
我的算法擊敗了90%的人,O(nlgn)算法比O(n)算法快。我覺得這個人是不懂算法的。讓我一步一步解釋。
?
# O的含義
通俗的說,O表示忽略系數的復雜度上限,常常用一個量級表示,比如n,nlgn。
?
# 忽略的系數重要嗎
重要。我覺得《算法》比《算法導論》優秀的原因之一是,作者用實例證明,在不少情況下,復雜度之前的系數很重要。比如,系數可以導致O(n^2)的插入排序可以比O(nlgn)快速排序快。
可以看一個例子。
// 偽代碼,程序1 void add(int num) {num++;num++;num++;num++;num++;num++;num++;num++;num++;num++; }void add(int[] nums) {for (int i = 0; i < n; i++)add(nums[i]); } // 偽代碼,程序2 void add(int num) {num++; }void add(int[] nums) {for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)add(nums[i]); }程序1的時間復雜度為O(n),程序2的時間復雜度為O(n^2)。如果從O來看,程序2的執行速度一定會比程序1快。
實際上速度相當。假設nums的大小為10,程序1要執行10 * 10 = 100次i++,程序2同樣執行10 * 10 * 1 = 100次i++。
原因就在于,程序1需要的時間是10 * n,系數很大為10,而程序2需要的時間是1 * n ^ 2,系數很小為1。
?
# 那個人錯在哪里
或許不是他的錯,是LeetCode的錯。
漸進時間一定要在系數相對于數據量比重很小很小的時候,才有用。像排序算法一類比較簡單的算法,需要上十萬的數據量,才能體現出復雜度為nlgn和n^2的細小區別。
這個人用了很聰明很簡單的算法,沒有用復雜的數據結構,全是基本變量,時間復雜度為O(nlgn)。而O(n)用了Hashtable,共有n個數,對于每個數,Hashtable里面有很多計算的過程,系數很大。
此題,LeetCode可能單個數據集不是很大,系數顯得格外重要。
?
# 鏈接
Q: https://leetcode.com/problems/two-sum/
A:?https://github.com/mofadeyunduo/LeetCode/tree/master/1TwoSum
(請多多支持我剛剛建立的GitHub和博客,謝謝,有問題可以郵件609092186@qq.com或者留言,我盡快回復)
?
轉載于:https://www.cnblogs.com/Piers/p/5747688.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的我们为什么不能只用O记号来谈论算法?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 台式机 双显卡切换实战
- 下一篇: 部分网站公开数据的汇总(2)