線上程式設計介紹
阿裡雲開發者社群線上程式設計産品,針對廣大開發者學習、實踐、面試、應聘、考試認證等打造的免費線上刷題神器。題庫來自筆試模拟題、算法大賽模拟題等,界面整潔明了,操作簡單,為使用者營造專心答題的學習環境。點選連結開始體驗:
https://developer.aliyun.com/coding本文為大家介紹其中的 第97題:破譯密碼 的題目解析,具體如下:
題目描述
題目等級:中等
知識點:尺取法
檢視題目:破譯密碼給你一個長度為n的序列,元素标号1-n。問能夠找到多少對不同的(L,R)(1 <= L <= R),使得在子序列[L,R]記憶體在出現頻率不低于K的元素?
輸入序列大小n(1 <= n <= 10^4)、出現頻率k(1 <= k <= n)和一個包含n個整數的數組,第i個整數表示序列的第i個元素為ai(1 <= ai <= 10^9)。
輸出滿足條件的子序列個數。
示例1
輸入:
4
2
[1 ,2 ,1 ,2]
輸出:
3
注意
三個子序列分别為[1,3],[1,4],[2,4]
解題思路:尺取法
與57超級區間那道題是類似的方法。
設目前區間為[L, R]。初始L = R = 0;使用尺取法需要判斷什麼時候調整L和R。
情況1:假設對于某個區間[L1, R1]滿足題目要求。則保持L1不變,依次增加R1直到n為止的所有區間都滿足題目的要求。
情況2:假設對于某個區間[L2,R2]不滿足題目要求。則需要保持L2不動,增加R2才可能滿足滿足題目要求。
情況3:是情況2拓展。如果[L2,n]不滿足題目要求,則任何i>L2,區間[i, n]都不滿足題目要求。
使用一個 2*n 的數組numb來記錄目前區間[L, R]内每個元素的出現次數。numbL和numbR表示區間[L, R]對應的numb數組範圍。因為每個數都是按照進入區間[L, R]的順序離開區間[L, R]的,相當于一個隊列,是以numb數組可以用numbL和numbR來表示目前區間[L, R]内的元素,而不用考慮中間某個數不在區間[L, R]内的情況。
計算過程
- 初始L = R = 0;sum = 0; 用來計算滿足條件的區間個數
- 判斷區間 [L, R] 的情況,滿足情況1,則sum++; R++。滿足情況2, L++。滿足情況3,結束計算。
- R每次加1,都要給numb數組中對應的數出現次數+1。當是一個新數時,要使numbR++;
-
L每次減1,都要給numb數組中對應的數出現次數-1。當減為0時,要使numbL++
對于情況1,因為L不變時,後面的所有R都滿足條件,是以可以修改為sum+=n-R+1; L++。
時間複雜度O(n^2) 修改之前最差為O(n^2)
空間複雜度O(2*n) numb數組的空間
看完之後是不是有了想法了呢,快來練練手吧>>
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SMxQTZ0YTOjZDZ1QTY2MWO0YmM0MDM3EGMzQzNiZjNw8CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)