《LeetCode之每日一题》:120.等差数列划分
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:120.等差数列划分相关的知识,希望对你有一定的参考价值。
题目链接: 等差数列划分
有关题目
如果一个数列 至少有三个元素 ,
并且任意两个相邻元素之差相同,
则称该数列为等差数列。
例如,[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
题解
法:动态规划
思路:
定义状态:
dp[i]表示从nums[0]到nums[i]且以nums[i]为结尾的
等差数列子数组的数量。
解释:如果nums[i]能和nums[i-1]nums[i-2]组成等差数列,
则以nums[i-1]结尾的等差数列均可以nums[i]结尾,
且多了一个新等差数列[nums[i],nums[i-1],nums[i-2]]
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, 0);//包含初始化dp
for (int i = 2; i < n; ++i){
if (nums[i - 2] - nums[i - 1] == nums[i - 1] - nums[i]){
dp[i] = dp[i - 1] + 1;
}
else {
dp[i] = 0;
}
}
return accumulate(dp.begin(), dp.end(), 0);
}
};
时间复杂度:O(N)
空间复杂度:O(N)
法:双指针
参考宫水三叶
思路:
关键还是得辨认出,在i, i + 1, i + 2……为等差数列的情况下,
每添加一个成等差的数字,那么相应的子数组大小3,4,……的数量也会增加1
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
int n = nums.size(), ans = 0;
for (int i = 0; i < n - 2;){//这边i 从 2开始就有瑕疵了
int j = i, d = nums[i] - nums[i + 1];
while(j + 1 < n && nums[j] - nums[j + 1] == d) ++j;
int len = j - i + 1;
// a1:长度为 len 的子数组数量;an:长度为 3 的子数组数量
int a1 = 1, an = len - 3 + 1;
//符合条件的子数组进行,高斯求和(等差数列求和)
int cnt = (a1 + an) * an / 2;
ans += cnt;
i = j;
}
return ans;
}
};
时间复杂度:O(N)
空间复杂度:O(1)
法:差分 + 计数
代码一:
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
int n = nums.size();
if (n < 3){
return 0;
}
int d = nums[0] - nums[1], t = 0;
int ans = 0;
for (int i = 2; i < n; ++i){
if (nums[i - 1] - nums[i] == d){
++t;
}
else {
d = nums[i - 1] - nums[i];
t = 0;
}
ans += t;//123 当4增加上去的时候,在123的基础上可加个4, 又加了2 3 4,所以++t
}
return ans;
}
};
代码二:
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
int n = nums.size(), t = 0, ans = 0;
for (int i = 2; i < n; ++i){
nums[i - 1] - nums[i] == nums[i - 2] - nums[i - 1] ? ans += ++t : t = 0;
}
return ans;
}
};
时间复杂度:O(N)
空间复杂度:O(1)
以上是关于《LeetCode之每日一题》:120.等差数列划分的主要内容,如果未能解决你的问题,请参考以下文章