《代码随想录》Ⅷ 贪心算法 376. 摆动序列
努力学习!
题目:力扣链接
-
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。 第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。
- 例如,
[1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值(6, -3, 5, -7, 3) 是正负交替出现的。 - 相反,
[1, 4, 7, 2, 5] 和[1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。
给你一个整数数组
nums ,返回nums 中作为 摆动序列 的 最长子序列的长度 。 - 例如,
一、思想
这道题的核心思想是使用贪心算法,通过记录摆动序列中的转折点来找到最长的摆动子序列。摆动序列的特点是相邻元素之间的差值在正负之间交替变化。我们可以通过遍历数组,记录每次差值变化的方向,从而确定摆动序列的长度。
具体来说,我们维护两个变量:prediff(前一个差值)和curdiff(当前差值)。如果prediff和curdiff的符号相反,说明出现了摆动,此时我们可以增加摆动序列的长度,并更新prediff为curdiff。通过这种方式,我们可以找到最长的摆动子序列。
二、代码
class Solution
{
public:
int wiggleMaxLength(vector<int> &nums)
{
// 如果数组长度小于等于1,直接返回数组长度
if (nums.size() <= 1) {
return nums.size();
}
// 初始化当前差值为0,前一个差值为0,结果长度为1
int curdiff = 0, prediff = 0, result = 1;
// 遍历数组,计算当前差值和前一个差值
for (int i = 0; i < nums.size() - 1; ++i) {
curdiff = nums[i + 1] - nums[i];
// 如果前一个差值小于等于0,当前差值大于0,或者前一个差值大于等于0,当前差值小于0,
// 那么更新结果长度,并将当前差值赋值给前一个差值
if ((prediff <= 0 && curdiff > 0) || (prediff >= 0 && curdiff < 0)) {
result++;
prediff = curdiff;
}
}
// 返回结果长度
return result;
}
};
三、代码解析
1. 算法工作原理分解
1.1 初始化
-
目的:处理特殊情况并初始化变量。
-
实现:
- 如果数组长度小于等于1,直接返回数组长度。
- 初始化
prediff(前一个差值)为0,curdiff(当前差值)为0,result(结果长度)为1。
1.2 遍历数组
-
目的:计算当前差值并判断是否出现摆动。
-
实现:
- 遍历数组,计算当前差值
curdiff = nums[i + 1] - nums[i]。 - 如果
prediff和curdiff的符号相反(即prediff <= 0 && curdiff > 0或prediff >= 0 && curdiff < 0),说明出现了摆动,此时增加result,并更新prediff为curdiff。
- 遍历数组,计算当前差值
1.3 返回结果
- 目的:返回最终计算出的最长摆动子序列的长度。
- 实现:返回变量
result的值。
2. 关键点说明
2.1 差值的计算与判断
- 差值计算:通过
nums[i + 1] - nums[i]计算当前差值。 - 摆动判断:如果
prediff和curdiff的符号相反,说明出现了摆动。
2.2 结果的更新
- 结果更新:每次出现摆动时,增加
result,并更新prediff为curdiff。
2.3 特殊情况的处理
- 特殊情况:如果数组长度小于等于1,直接返回数组长度。
四、复杂度分析
-
时间复杂度:
O(n)- 其中
n是数组的长度。算法只需要遍历数组一次,因此时间复杂度为O(n)。
- 其中
-
空间复杂度:
O(1)- 除了输入数组外,算法只使用了常数级别的额外空间,因此空间复杂度为
O(1)。
- 除了输入数组外,算法只使用了常数级别的额外空间,因此空间复杂度为
白展堂:人生就是这样,苦和累你总得选一样吧?哪有什么好事都让你一个人占了呢。 ——《武林外传》
712

被折叠的 条评论
为什么被折叠?



