LeetCode-413. 等差数列划分
1、题目描述:
如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。
- 例如,
[1,3,5,7,9]
、[7,7,7,7]
和[3,-1,-5,-9]
都是等差数列。
给你一个整数数组 nums
,返回数组 nums
中所有为等差数组的 子数组 个数。
子数组 是数组中的一个连续序列。
示例 1:
输入:nums = [1,2,3,4] 输出:3 解释:nums 中有三个子等差数组:[1, 2, 3]、[2, 3, 4] 和 [1,2,3,4] 自身。
示例 2:
输入:nums = [1] 输出:0
提示:
1 <= nums.length <= 5000
-1000 <= nums[i] <= 1000
2、代码
class Solution {
public:int numberOfArithmeticSlices(vector<int>& nums) {int n = nums.size();// 等差数列至少需要3个元素if (n < 3) return 0;// dp[i]表示以索引i结尾的等差数列的数目vector<int> dp(n, 0);int total = 0; // 记录所有等差子数组的总数// 从索引2开始遍历,因为等差数列至少需要前三个元素for(int i = 2; i < n; ++i) {// 判断是否构成等差数列:当前差等于前一个差if(nums[i] - nums[i - 1] == nums[i - 1] - nums[i -2]) {// 若构成等差数列,dp[i] = 以i-1结尾的数目 + 1(新增长度为3的数列)dp[i] = dp[i - 1] + 1;// 累加当前位置贡献的等差数列数目total += dp[i];}// 若不构成等差数列,dp[i]保持0(初始化值)}return total;}
};
3、解题思路
- 动态规划数组定义:定义一个数组
dp
,其中dp[i]
表示以位置i
结尾的等差数列的数目。 - 状态转移:对于位置
i
,如果nums[i] - nums[i-1] == nums[i-1] - nums[i-2]
,则dp[i] = dp[i-1] + 1
。这是因为如果当前位置能和前面的元素构成等差数列,那么以i
结尾的等差数列数目等于以i-1
结尾的数目加 1(新增的等差数列长度为 3)。 - 结果累加:遍历整个数组,将每个位置的
dp[i]
累加起来,得到最终结果。