專欄 | 九章演算法
網址 | www.jiuzhang.com
題目描述
對n個數的序列,a1,a2,……,an,判斷是否存在i<j<k,使得ai<ak<aj(這樣的[ai,aj,ak]被稱為132模式)。n不超過15000。
樣例1
輸入: [1,2,3,4]
輸出: False
樣例2
輸入: [3,1,4,2]
輸出: True
說明: [1,4,2]是一個132模式
樣例3
輸入: [-1,3,2,0]
輸出: True
說明: [-1,3,2],[-1,3,0],[-1,2,0]均為132模式
解題思路分析
1.一個顯而易見的暴力方法是
列舉i<j<k,再判斷是否有a(i)<a(k)<a(j)成立。這樣做的時間複雜度為O(n^3),對於題目給出的n的大小是無法接受的。
2.用min(j-1)代替a(i)
a. 令min(j)為a(1),a(2),……,a(j)中的最小值,那麼如果[a(i),a(j),a(k)]為一個132模式,則[min(j-1),a(j),a(k)]也必為132模式,反之,如果[min(j-1),a(j),a(k)]不是132模式,那麼對於任意i<j,[a(i),a(j),a(k)]都不會是132模式。
b. min(j)可以用O(n)的時間遞推出來,再列舉j,k,判斷是否有min(j-1)<a(j)<a(k),時間複雜度為O(n^2)。
3.用max(j)代替a(k)
a.與方法2相似,我們也可以省去對k的列舉。令max(j)為a(j+1),a(j+2),……,a(n)中小於a(j)的最大值,那麼a(k)即可用max(j)代替。與方法2中不同的是,此處要求的不是a(j)以後的數中的最大值,而是要小於a(j)的最大值,這個問題當然可以用線段樹或者平衡樹來處理,但過於複雜,其實用棧就可以處理這個問題。
b. 我們從後往前列舉j,如果棧頂元素小於a(j),則將棧頂元素出棧,直到棧為空或棧頂元素不小於a(j),再將a(j)壓入棧。這樣就保證了,棧中元素由棧頂到棧底是非降序的,那麼在a(j)入棧前最後一個出棧的就是棧中小於a(j)的最大值。
c. 有一個小問題是,實際的max(j)可能在列舉到j之前就已經出棧了,而導致實際得到的值並非是a(j)以後小於a(j)的最大值,而只是列舉到j時的棧中小於a(j)的最大值,但這對於原問題的求解來說沒有影響,故仍把該值記為max(j),有興趣的讀者可以自己分析一下。
d. 得到max(j)後,判斷是否有min(j-1)<max(j),如果成立則存在132模式,否則繼續向前列舉j,如果對於所有的j均不成立,則不存在132模式。這樣,時間複雜度為O(n)。
4.Follow up:如何快速統計序列中132模式的組數?
這裡提供一個思路:從後往前列舉i,同時維護一組鍵值對{a(k),ans(k)},ans(k)表示滿足i
參考程式
面試官角度分析
這個問題主要考察對問題的分析預處理的能力,三種不同時間複雜度的演算法可以把面試者分成三類,是一道適合面試的好題。給出第二種演算法可以hire,給出第三種可以strong hire。
lintcode相關問題
九章參考答案
推薦閱讀:
- 《北美IT企業fulltime薪資大曝光》
- 《IT 簡歷模板大放送 | 《如何寫好技術簡歷》講座精華總結》
- 《offer收割機的求職祕訣 | <如何成為offer達人>講座精華總結》
- 《Google offer 如何談判?聽聽 Google recruiter 怎麼說!》
- 《面試遇到做過的題怎麼辦?》
- 《冷凍期大揭祕 | Google、FB、Amazon、Linkedin冷凍期》
- 《面試前如何瞭解一家IT企業?試試官方技術部落格!》
- 《北美IT企業intern薪資大曝光》
- 《16個behavior question 的面試官解析及tips》
- 《Google晉升機制 | 大公司如何升級打怪, 獲得晉升?》
歡迎關注我的微信公眾號:九章演算法(ninechapter)。
精英程式設計師交流社群,定期釋出面試題、面試技巧、求職資訊等