一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して7日目です。クリックしてイベントの詳細をご覧ください。
トピック
連続する数の差が正の数と負の数の間で厳密に交互になる場合、数列はウォブルシーケンスと呼ばれます。最初の違い(存在する場合)は、正または負の場合があります。1つの要素のみまたは2つの等しくない要素を持つシーケンスも、ウォブルシーケンスと見なされます。
たとえば 、差の値 が正と負の間で交互[1, 7, 4, 9, 2, 5]
になるため、ウォブルシーケンス。(6, -3, 5, -7, 3)
対照的に、[1, 4, 7, 2, 5]
sum [1, 7, 4, 5, 5]
はウォブルシーケンスではありません。最初の2つは最初の2つの差が正であり、2つ目は最後の差がゼロであるためです。サブシーケンスは、元のシーケンスからいくつかの(またはそうでない)要素を削除し、残りの要素を元の順序のままにすることで取得できます。
整数の配列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
复制代码
答え
問題解決分析
問題解決のアイデア
-
この問題は、典型的な動的計画法の問題です。
-
スイングシーケンスの一部となる要素を選択するときはいつでも、その要素は前の要素のサイズに応じて上下します。その場合、リスト状態式は次のようになります。
-
up[i]
i
前の要素の1つで終わる最長の「立ち上がりウィグルシーケンス」の長さを示します。 -
down[i]
i
前の要素の1つで終わる最長の「立ち下がりウォブルシーケンス」の長さを示します。
up[i]
3つの場合、
nums[i] > nums[i-1]
up[i] = fmax(up[i-1], down[i-1] + 1);
down[i] = down[i-1];
复制代码
nums[i] < nums[i-1]
up[i] = up[i-1];
down[i] = fmax(up[i-1] + 1, down[i-1]);
复制代码
- ついに結果が出ました
up[numsSize -1], down[numsSize -1]
。
複雑さ
時間の複雑さ:O(N)
空間の複雑さ:O(N)
問題解決コード
ソリューションコードは次のとおりです(コード内の詳細なコメント):
int wiggleMaxLength(int* nums, int numsSize){
if (numsSize < 2) {
return numsSize;
}
int up[numsSize], down[numsSize];
up[0]= down[0] =1;
for (int i=1; i< numsSize; i++) {
if (nums[i] > nums[i-1]) {
up[i] = fmax(up[i-1], down[i-1] + 1);
down[i] = down[i-1];
} else if (nums[i] < nums[i-1]) {
up[i] = up[i-1];
down[i] = fmax(up[i-1] + 1, down[i-1]);
} else {
up[i] = up[i-1];
down[i] = down[i-1];
}
}
return fmax(up[numsSize -1], down[numsSize -1]);
}
复制代码
送信後のフィードバック結果(このトピックは最適化されていないため、パフォーマンスは平均的です):