map+DP leetcode446
?
如果數字序列由至少三個元素組成并且任何兩個連續元素之間的差異相同,則稱為算術序列。
例如,這些是算術序列:
1,3,5,7,9?
7,7,7,7?
3,-1,-5,-9?
以下序列是不算術。
1, 1, 2, 5, 7
給出了由N個數組成的零索引數組A. 該陣列的子序列切片是任何整數序列(P0,P1,...,Pk),使得0≤P0<P1 <... <Pk <N。
如果序列A [P0],A [P1],...,A [Pk-1],A [Pk]是算術的,則陣列A的子序列片(P0,P1,...,Pk)被稱為算術。特別是,這意味著k≥2。
該函數應返回數組A中的算術子序列片數。
輸入包含N個整數。每個整數的范圍為-231和231-1,0≤N≤1000。輸出保證小于231-1。
例:
輸入:[2,4,6,8,10]
輸出:7
說明:
所有算術子序列切片為:
[2,4,6]?
[4,6,8]?
[6,8,10]?
[2,4,6,8]?
[4,6,8,10]?
[2,4,6,8,10]?
[2,6,10]
?
?
簡單的子序列這種題,一般思路先想到的dp就是設置以第i個元素結尾的一種狀態,然后能推到最后吧?
比如最長遞增子序列這種的題。
?
那我們就試試:dp[i]代表以第i個元素結尾的等差數列的個數。
然后我們想一下狀態轉移方程是什么?
我們會發現,挺難推出來的。。因為對于本個元素,最容易想的思路就是把前面的結尾都遍歷一遍,然后能組成等差數列的都加起來吧?
但是我們無法判斷之前的結尾組成的等差數列中,加上第i個元素還能不能是等差數列。。。
比如第5個數是5,能和前面組成1,2,3,4,5和2,3,4,5和3,4,5和1,3,5這幾個序列,那dp[4]應該是4咯,我們對于后面的結尾,比如數字7,算dp時,遍歷到dp[4]了,我們無法判斷dp[4]里這四個序列有幾個公差為7-5=2(也就是能組成)。
我之前寫過,動態規劃就是空間優化時間的算法。
我們推不出來,因為信息不全。需要記錄更多的信息。我們不止要知道dp[i]是多少,還要知道每個公差的序列有多少,才能推出來之后的dp序列。
我們可以二維dp[a][b]表示第a個元素結尾公差為b的序列個數,但是由于數據較為稀疏,浪費空間時間較大,我們可以map走一波。
比如上面那個例子,我們要記錄:dp[4],公差為1的序列有仨,公差為2的有一個。
這樣,我們之后遇到了6,那6-5=1,dp[4]里有三個序列公差為1,我們就能知道這三個序列加上6還是等差的。
遇到7,也能7-5=2,找dp[4]中公差為2的即可。
?
還有一個需要注意的點:題目說長度最小為3才算。
過程敘述:
計算兩個數字之差diff,如果越界了不做處理
如果沒越界,dp[i]中diff的映射增1,然后看dp[j]中是否有diff的映射
如果有的話,說明此時已經能構成等差數列了(三個數),將dp[j][d]加入結果res中,然后再更新dp[i][d]
這樣等遍歷完數組,res即為總數。
#include <iostream> #include <vector> #include <map> #include <set> #include <queue> #include <stack> #include <string> #include <climits> #include <algorithm> #include <sstream> #include <functional> #include <bitset> #include <cmath>using namespace std;class Solution { public:int numberOfArithmeticSlices(vector<int>& A) {if (A.size() <= 2)return 0;int count = 0;vector<map<int, int>> dp(A.size());for (int i = 0; i < A.size(); i++){for (int j = 0; j < i; j++){if ((long)A[i] - (long)A[j] > INT_MAX || (long)A[i] - (long)A[j] < INT_MIN) continue;//節省時間int diff = A[i] - A[j];//公差dp[i][diff] += 1;if (dp[j].find(diff) != dp[j].end()) //能構成至少三個數等差{dp[i][diff] += dp[j][diff];count += dp[j][diff];}}}return count;} };
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的map+DP leetcode446的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MYSQ产品
- 下一篇: leetcode162. 寻找峰值 变种