給定乙個整數陣列 a,返回 a 中最長等差子串行的長度。
回想一下,a 的子串行是列表 a[i_1], a[i_2], …, a[i_k] 其中 0 <= i_1 < i_2 < … < i_k <= a.length - 1。並且如果 b[i+1] - b[i]( 0 <= i < b.length - 1) 的值都相同,那麼序列 b 是等差的。
示例 1:
輸入:[3,6,9,12]
輸出:4
解釋:整個陣列是公差為 3 的等差數列。
示例 2:
輸入:[9,4,7,2,10]
輸出:3
解釋:最長的等差子串行是 [4,7,10]。
示例 3:
輸入:[20,1,15,3,10,5,8]
輸出:4
解釋:最長的等差子串行是 [20,15,10,5]。
2 <= a.length <= 2000
0 <= a[i] <= 10000
這道題看起來和最長上公升子串行很相似,所以我們也是用相似的思路,整體複雜度為o(n2),看資料的範圍也不會超.
首先在每乙個維度記錄乙個和等差項大小相關的資料結構,一般常用vector,這時dp[i][j]=a;表示,從開頭到第i個元素差值為j的最長序列長度為a.動態轉移方程也很好想了,就是
for
(int i=
1;i++i)
}
進行遍歷,更新檢視每乙個j的a[i]-a[j]的差值tmp,更新的值是dp[i][tmp],再去看dp[j][tmp]的值為多少,沒有這一項的化就天2,表示i,j項,有的化就是加1.
dp[i][tmp]=max(dp[j][tmp]+1,dp[i][tmp]);
dp[i][tmp]=2;
兩種情況,由於我們定義的dp[i][tmp]的含義是以i為結尾的最長,所以每一次更新dp都要更新ans值
基本思路就是這樣,並且也能過,**如下:
class
solution
}return res;}}
;
最可氣的是我在之前的經驗感覺這個二維的vector優點慢,把第二層的vector換成了unordered_map,然後更新的是map裡的值,反而不過了
// 55/62
class
solution
else
ans=
max(ans,memo[i]
[tmp]);
}}return ans;}}
;
我又想起了那個題的陣列壓縮的辦法,所以如法炮製,把二維的陣列壓縮成乙個一維的數,看準了a.length()<2000,第二維向左移動12位(212>2000),後面的加上第一維就可以,所有的壓縮後的數放到unordered_map裡,這再不過,我…
// 53/65
class
solution
else
ans=
max(ans,memo[idx2]);
}}return ans;}}
;
這leetcode負值還不能左移,要我再加上乙個offset.
這過的更少了,無言以對.看了一下有乙個過的寫了二維的vector(**1),我陷入了深深的沉思…
還是看看別人的做法吧
class
solution
mp[a[i]
]= i;
}return ans;}}
;/**/
這個占用的空間小很多(雖然沒看出來小在哪,開了二維的vector還有map**小了!)
整體思路是相同的但是在找的時候,每經過乙個元素,把他放到map裡,表示前面出現過這個元素,在之後的找裡,因為你知道了a[i],a[j],那麼你就可以知道他的上乙個是多少了,因為你知道了差值,知道了這一項,所以知道了上一項是多少,你之前還記錄了所有的元素,所以也知道了所有.有乙個疑點,如果出現相同的a[i],會更新掉,會不會有bug.
貪心證明?最後乙個永遠好於前面的相同元素?
1027 最長等差數列
題意 給定乙個整數陣列 a,返回 a 中最長等差子串行的長度。回想一下,a 的子串行是列表 a i 1 a i 2 a i k 其中 0 i 1 i 2 i k a.length 1。並且如果 b i 1 b i 0 i b.length 1 的值都相同,那麼序列 b 是等差的。思路 dp i j ...
Leetcode 最長子串
給定乙個字串,找出不含有重複字元的最長子串的長度。示例 給定 abcabcbb 沒有重複字元的最長子串是 abc 那麼長度就是3。給定 bbbbb 最長的子串就是 b 長度是1。給定 pwwkew 最長子串是 wke 長度是3。請注意答案必須是乙個子串,pwke 是 子串行 而不是子串。includ...
LeetCode 最長有效括號
方法一 方法二 給定乙個只包含 和 的字串,找出最長的包含有效括號的子串的長度。示例 1 輸入 輸出 2 解釋 最長有效括號子串為 示例 2 輸入 輸出 4 解釋 最長有效括號子串為 有效的括號 括號的生成 出棧入棧方法 參考之前的有效括號題目,當 前乙個為 則刪除這對,當全部刪除則為有效括號。在棧...