壹 ❀ 引
昨天下班后,還是找經理提出了辭職,沒有猶豫的裸辭,今天與人事的對話不小心被后台的同事聽到,一下在公司傳開了,下午我與同事們多人對線,被他們的消息轟炸....沒錯,我真的要走了。
因為什么原因呢?公司技術框架過於落后(angularjs1.6,不允許使用ES6等),很長時間我都很焦慮,擔心自己再待下去是否會被這個行業淘汰,在過去的時間也學了一些東西,但都沒法在工作中實踐,以及待遇等等問題縈繞於心,才出此決策。
在與獵頭的溝通中對方也是建議我先待着看看,不推薦裸辭,畢竟疫情影響行情不容樂觀。我說如果當下處境良好我定會觀望,只是深處溫室之中越久,自己反而越害怕離職,涅槃重生還需經歷烈火考驗,比起騎驢找馬,我還是更擅長破釜沉舟一點,祝自己好運。
還有一個月的工作交接期,順便復盤自己的工作經歷,還要復習,刷題,學習vue等等,壓力巨大。不過既然是自己的決定,那就努力做到最好就好了。當然,后續面試我也會不斷更新相關面試經歷,多總結多積累,總沒壞處。
好了,說了這么多,來看看今天的題目吧,題目來自121. 買賣股票的最佳時機,題目描述如下:
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。
如果你最多只允許完成一筆交易(即買入和賣出一支股票一次),設計一個算法來計算你所能獲取的最大利潤。
注意:你不能在買入股票前賣出股票。
示例 1:
輸入: [7,1,5,3,6,4] 輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。
注意利潤不能是 7-1 = 6, 因為賣出價格需要大於買入價格;同時,你不能在買入前賣出股票。
示例 2:輸入: [7,6,4,3,1] 輸出: 0
解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。
讓我們簡單分析題目,嘗試解決它。
貳 ❀ 題解分析
其實當我看到[7,1,5,3,6,4]
的例子,我第一反應也是為啥不是7-1=6
,其實在題目的注意已經說明,我們在賣出股票時,必須得先買入,想要賺的多,一定是在歷史最低價買入,在歷史最高價賣出。注意,這個歷史最低並不是數組中最小值,比如[3,5,1,2]
這個例子,雖然我們在1買入最低,但后面價格只有2,利潤反而不如3買入后5賣出。
我們需要理清的一點是,比如在第i天賣出,那么一定是在i-1天中最小的價格買入,因為得先買才能后賣,所以最笨的做法就是使用雙循環,用嘗試算出每一個i天與之前(i-1,i-2...)的差價,再找出其中最大的一個值即可,比如:
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function (prices) {
// 因為如果沒有利潤就是0,這里初始化
let maxProfit = 0;
for (let i = 0; i < prices.length; i++) {
// 注意,這里的j從i+1開始
for (j = i + 1; j < prices.length; j++) {
let profit = prices[j] - prices[i];
// 不斷用當前利潤和歷史最大利潤比較,如果更大就替換maxProfit
if (profit > maxProfit) {
maxProfit = profit;
};
};
};
return maxProfit;
};
很簡單也非常好懂,但是我們也清楚,這個耗時太久,只要價格數據越大,我們查詢代價就越大。那么有沒有更好的做法呢?當然有。
其實找到最大利潤,其實無非就是找到歷史最低價格,但事實上我們不知道哪個是最低價,沒關系,我們可以先假設第一天是最低,遍歷數組的同時,讓當前價格與歷史最低比較,如果更低,那自然要更新歷史最低價了。
更新了最低價之后呢?當然是用當前價格減去歷史最低價求出利潤,並與歷史比較,始終記錄較大的利潤即可,直到遍歷結束,返回最終的價格不就是最大的利潤了,比如:
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function (prices) {
let maxProfit = 0,
// 假設0位價格為歷史最低
minPrice = prices[0];
// i從1開始
for (let i = 1; i < prices.length; i++) {
// 如果后續價格比歷史更低,更新最低價
minPrice = Math.min(minPrice, prices[i]);
// 計算利潤,找出最大利潤
maxProfit = Math.max(maxProfit, prices[i] - minPrice);
};
return maxProfit;
};
我們來以[7,6,4,3,1]
這個例子來看,由於價格越來越低,最低價格也一直隨便遍歷變化,導致利潤計算始終為0,而對於第一個例子,一旦鎖定了一個歷史低價,后續要做的就是不斷與之后的價格比較,從中找到最大利潤。
這個思路也叫動態規划,雖然我現在也不是很理解- - ,看后續做題能否積累,那么本文就到這里就結束了。