刷题一个4ms的程序,代码如何优化到3ms再到2ms?
目錄
- 前言
- 具體
- 結語
如果覺得本文有所幫助,記得點贊收藏!
前言
你在打王者榮耀的時候,是否經常會遇到這種情況:和對面同位置對線的時候,自己也沒有太大失誤,但是為啥對面經濟比我高?能夠壓著我打?——是我太菜了
這可能就是你們細節上的差距,別人可能對兵線、技能、英雄機制搞得更清楚,每一步都清清楚楚,刷題也是一樣,同樣的方法,為啥別人的比你快很多,也需要注意一下細節。
筆者最近再刷LeetCode,對于正常一道題來說,時間的耗費有兩個差距:
時間復雜度的差距
時間復雜度上的差距,因為很多題正常的暴力是O(n2)甚至更慢的時間復雜度,這些方法就算能過但是時間耗費很長,如果你發現你的算法過的時間在后30%那就說明你的方法不對了。在復雜度的差距差的可能幾百毫秒,幾十毫秒,而快的可能是幾毫秒。
細節上的差距
很多題可能大家能夠想到的比較好的方法的時間復雜度可能差不多,自己也是幾毫秒但是自己的排名依然在50%-60%左右,這到底是為什么呢?是因為你的細節還需要優化,你整體復雜度雖然掌握了,但是你可能多算了幾次循環,幾次運算。所以當條件允許你需要靜下來思考下怎么樣才能讓自己的程序跑在前90%以上。怎樣去優化這個時間。
具體
筆者就拿今天刷的這道力扣題來講講,力扣的第11題,思路很清晰就是從兩邊向中間動態壓縮區間,是一個O(n)的時間復雜度。
筆者第一次使用這個寫法是4ms:
public int maxArea2(int[] height) {int max = 0;int left = 0;int right = height.length - 1;while (left < right) {max = Math.max(max, Math.min(height[left], height[right]) * (right - left));if (height[left] > height[right])// 右側更小right--;else {left++;}}return max;}
但是我在研究這段代碼時候發現以下幾點問題可以優化:
- 使用Math.max()判斷最大值最小值的時候,下面在判斷是左指針右移還是右指針左移動重復判斷了,我們可以手動比較大小重復利用這次計算去完成相同的操作。
這樣的一部優化之后時間來到了穩定的3ms:
還能繼續優化嘛?當然能:
- Math.max()返回double類型轉成int需要一定成本,然而我們數據本身就是int類型可以直接計算。
- 對數組取值的時候,比較取一次(兩個值),計算取一次(一個值),而我們知道數組其實在內存中我們通過0號位置計算得到我們對應位置的數值,所以我們可以把3次計算減少成2次,用兩個空間leftvalue和rightvalue記錄左右數組位置的值。
通過上面的優化得到下面的代碼:
public int maxArea4(int[] height) {int max = 0;int left = 0;int right = height.length - 1;int team = 0;int leftvalue=0;int rightvalue=0;while (left < right) {leftvalue=height[left];rightvalue=height[right];if (leftvalue < rightvalue) {team = leftvalue * (right-left);if(max<team) {max=team;}left++;} else {team = rightvalue * (right-left);if(max<team) {max=team;}right--;}}return max;}成功步入2ms大軍。
還能到1ms嘛?
- 我是暫時不能了,,各位大佬請便!
結語
雖然這些優化并沒有得到質的改善,并且可能也比較初級,但是刷題的同時通過這種不斷優化能夠增加對計算機執行和原理的理解:哇,原來是這樣。并且如果有時間養成這樣的好習慣,相信不就以后,未來的調優專家就是你了!
如果覺得不過,記得點贊關注哦!公眾號:bigsai,回復bigsai獲得筆者珍藏學習資源。
總結
以上是生活随笔為你收集整理的刷题一个4ms的程序,代码如何优化到3ms再到2ms?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 11盛水最多的容器12
- 下一篇: LeetCode 13罗马数字转整数14