time: 20190906
type: medium
以下數列不是等差數列。
1, 1, 2, 5, 7
陣列 a 包含 n 個數,且索引從0開始。陣列 a 的乙個子陣列劃分為陣列 (p, q),p 與 q 是整數且滿足 0<=p如果滿足以下條件,則稱子陣列(p, q)為等差陣列:
元素 a[p], a[p + 1], …, a[q - 1], a[q] 是等差的。並且 p + 1 < q 。
函式要返回陣列 a 中所有為等差陣列的子陣列個數。
示例:a = [1, 2, 3, 4]
返回: 3, a 中有三個子等差陣列: [1, 2, 3], [2, 3, 4] 以及自身 [1, 2, 3, 4]。
本題也是dp演算法,定義f[i]
表示以到i
元素為止的等差數列個數。因為等差數列只有3個和3個元素以上才有等差的意義因此,我們從f[2]
開始往後計算。
當a[i] - a[i-1] = a[i-1] - a[i-2]
時,表示至少過去3個元素是等差數列。這是新增的,且f[i-1]
如果不為0,則表示在過去3個元素中,有延續。
f[i] = f[i-1] + 1
若過去三個元素是等差。
f
初始化是全部為0的。下面舉兩個典型的例子來說明狀態轉移方程:
從3開始,f[2] = 1
,因為過去3個元素1,2,3是等差的。現在觀察4,過去三個元素2,3,4也是等差的,f[2]
大於0,表示4和過去4個元素也能湊成等差。可以觀察到乙個性質,如果在等差數列之後出現乙個非下乙個等差元素,f[i]
就不會被更新,就是初始值0。
因此,f[3] = f[2] + 1 => 2
,表示[2,3,4], [1,2,3,4]。
再看元素5,求f[4]
,過去三個元素3,4,5滿足等差,f[3]
對應的數列補上元素5還是等差,加上新開拓的[3,4,5]
,得出f[4] = f[3] + 1 ⇒ 3
。
注意這種得出的結果,最後全部累加才是最後的結果。
第二種情況裡,在等差數列之後出現非下乙個等差元素,f
陣列元素為0。
不再多說,理解本題的動態規劃,核心在於理解這個性質:
如果在等差數列之後出現乙個非下乙個等差元素,f[i]
就不會被更新,就是初始值0。
class
solution
:def
numberofarithmeticslices
(self, a: list[
int])-
>
int:
# 至少3個才叫數列,才有等差這種概念
# f[i]表示到i元素為止的等差數列個數,差(d)是一樣的
# a[i] - a[i-1]等於a[i-1] - a[i-2],則f[i] = f[i-1] + 1
# 從左往右更新
n =len(a)
f =[0
]* n
if n <3:
return
0# f[0], f[1], f[2]
for i in
range(2
, n)
:if a[i]
- a[i-1]
== a[i-1]
- a[i-2]
: f[i]
= f[i-1]
+1# print(f)
return
sum(f)
end. Leetcode 413 等差數列劃分
如果乙個數列至少有三個元素,並且任意兩個相鄰元素之差相同,則稱該數列為等差數列。例如,以下數列為等差數列 1,3,5,7,9 7,7,7,7 3,1,5,9 以下數列不是等差數列。1,1,2,5,7陣列 a 包含 n 個數,且索引從0開始。陣列 a 的乙個子陣列劃分為陣列 p,q p 與 q 是整數...
Leetcode 413 等差數列劃分
如果乙個數列至少有三個元素,並且任意兩個相鄰元素之差相同,則稱該數列為等差數列。例如,以下數列為等差數列 1,3,5,7,9 7,7,7,7 3,1,5,9以下數列不是等差數列。1,1,2,5,7陣列 a 包含 n 個數,且索引從0開始。陣列 a 的乙個子陣列劃分為陣列 p,q p 與 q 是整數且...
Leetcode 413 等差數列劃分
如果乙個數列至少有三個元素,並且任意兩個相鄰元素之差相同,則稱該數列為等差數列。例如,以下數列為等差數列 1,3,5,7,9 7,7,7,7 3,1,5,9 以下數列不是等差數列。1,1,2,5,7 陣列 a 包含 n 個數,且索引從0開始。陣列 a 的乙個子陣列劃分為陣列 p,q p 與 q 是整...