一、题目描述
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。
-
例如,
[1, 7, 4, 9, 2, 5]
是一个 摆动序列 ,因为差值(6, -3, 5, -7, 3)
是正负交替出现的。 - 相反,
[1, 4, 7, 2, 5]
和[1, 7, 4, 5, 5]
不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。
给你一个整数数组 nums
,返回 nums
中作为 摆动序列 的 最长子序列的长度 。
示例 1:
输入:nums = [1,7,4,9,2,5] 输出:6 解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。
示例 2:
输入:nums = [1,17,5,10,13,15,10,5,16,8] 输出:7 解释:这个序列包含几个长度为 7 摆动序列。 其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8) 。
示例 3:
输入:nums = [1,2,3,4,5,6,7,8,9] 输出:2
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
二、解题思路
- 首先需要明确的是,摆动序列的特点是相邻元素之间的差值交替正负。
- 可以使用贪心算法来解决这个问题。遍历数组,维护两个变量,分别记录上一个上升摆动和上一个下降摆动的位置。
- 对于当前遍历到的元素,如果它与上一个上升摆动元素或上一个下降摆动元素的差值满足摆动序列的定义,则更新相应的摆动位置,并且摆动序列长度加一。
- 最后,摆动序列的长度就是经过的摆动次数加一(因为第一个元素不计入摆动)。
三、具体代码
class Solution {
public int wiggleMaxLength(int[] nums) {
int n = nums.length;
if (n < 2) return n;
int up = 1, down = 1; // up和down分别代表上一个上升摆动和下降摆动的长度
for (int i = 1; i < n; i++) {
if (nums[i] > nums[i - 1]) {
up = down + 1; // 如果当前元素比前一个元素大,更新上升摆动的长度
} else if (nums[i] < nums[i - 1]) {
down = up + 1; // 如果当前元素比前一个元素小,更新下降摆动的长度
}
}
// 最后的摆动序列长度是最后一次上升或下降摆动的长度
return Math.max(up, down);
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 代码中有一个循环,它遍历数组
nums
一次,数组的长度为n
。 - 在这个循环中,执行的操作(比较和赋值)都是常数时间的操作。
- 因此,整个循环的时间复杂度是O(n),其中n是数组
nums
的长度。 - 循环之外的操作(包括数组长度的检查和最终返回最大值)都是常数时间的操作,不会影响总的时间复杂度。
综上所述,代码的时间复杂度是O(n)。
2. 空间复杂度
- 代码使用了固定数量的变量:
n
用于存储数组的长度,up
和down
用于记录摆动序列的长度。 - 这些变量都是基本数据类型,占用的空间不随输入数组
nums
的大小而变化。 - 因此,无论输入数组的大小如何,所需的空间都是恒定的。
综上所述,代码的空间复杂度是O(1)。
五、总结知识点
-
类定义:
class Solution
:定义了一个名为Solution
的类。
-
方法定义:
public int wiggleMaxLength(int[] nums)
:定义了一个公共方法wiggleMaxLength
,它接受一个整型数组nums
作为参数,并返回一个整型值。
-
数组操作:
int n = nums.length;
:获取数组的长度。
-
条件判断:
if (n < 2) return n;
:如果数组长度小于2,直接返回数组的长度,因为长度小于2的数组本身就是摆动序列。
-
循环结构:
for (int i = 1; i < n; i++)
:使用for
循环遍历数组,从第二个元素开始,因为第一个元素没有前一个元素与之比较。
-
逻辑判断:
if (nums[i] > nums[i - 1])
:比较当前元素与它的前一个元素,判断是否上升。else if (nums[i] < nums[i - 1])
:如果当前元素小于前一个元素,判断是否下降。
-
变量赋值:
up = down + 1;
:当出现上升摆动时,更新上升摆动的长度。down = up + 1;
:当出现下降摆动时,更新下降摆动的长度。
-
数学操作:
return Math.max(up, down);
:使用Math.max
方法返回上升摆动和下降摆动长度的最大值,这代表摆动序列的最大长度。
-
初始化变量:
int up = 1, down = 1;
:初始化两个变量up
和down
,它们分别代表最后一次上升和下降摆动的长度,初始值为1,因为数组至少有一个元素。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。