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