413. 等差数列划分
方法一:暴力
class Solution:
def numberOfArithmeticSlices(self, nums: List[int]) -> int:
def isArithmeticProgression(x):
n = len(x)
# if n < 3:return False
d = x[1] - x[0]
for i in range(2, n):
if x[i] - x[i-1] != d: return False
return True
res, n = 0, len(nums)
if n < 3:return 0
for i in range(n):
for j in range(i + 2, n):
if isArithmeticProgression(nums[i:j+1]): res += 1
else: break
return res
方法二:双指针(滑动窗口)
class Solution:
def numberOfArithmeticSlices(self, nums: List[int]) -> int:
n, res = len(nums), 0
# if n < 3: return 0
for i in range(1,n):
d = nums[i] - nums[i - 1]
for j in range(i + 1, n):
if nums[j] - nums[j - 1] == d: res += 1
else: break
return res
方法三:动态规划
定义 dp[i] 是以 nums[i] 为终点的等差数列的个数。
初始状态:dp[0] = 0
转移方程:
返回:sum(dp)
class Solution:
def numberOfArithmeticSlices(self, nums: List[int]) -> int:
n = len(nums)
dp = [0] * n
for i in range(2, n):
if nums[i - 2] + nums[i] == nums[i - 1] * 2:
dp[i] = dp[i - 1] + 1
return sum(dp)
由于 dp[i] 只和 dp[i - 1] 有关,所以可以进行状态压缩,只用一个变量 k 来表示以 nums[i] 为终点的等差数列的个数。
方法四:简化
cclass Solution:
def numberOfArithmeticSlices(self, nums: List[int]) -> int:
n, k, res = len(nums), 0, 0
for i in range(2, n):
if nums[i] + nums[i - 2] == 2 * nums[i - 1]:
k += 1
res += k
else:
k = 0
return res