一个整数序列,如果两个相邻元素的差恰好正负(负正)交替出现,则该序列被称为
摇摆序列。一个小于2个元素的序列直接为摇摆序列。给一个随机序列,求这个序列满足摇摆序列定义的最长子序列的长度:

输入[1,17,5,10,13,15,10,5,16,8],结果为7([1,17,10,13,10,16,8] )

序列 [1, 7, 4, 9, 2, 5],相邻元素的差 (6, -3, 5, -7, 3),则为摇摆序列,结果为6
序列 [1,4,7,2,5] (3, 3, -5, 3)、 [1,7,4,5,5] (6, -3, 1, 0)不是摇摆序列,结果为2

根据贪心算法的核心:

  1. 寻找数据规律
  2. 使用最优的迭代策略

分析:

  • 规律
    很明显,摇摆序列的判定并不支持存在连续三个或者更多元素是递增或者递减的情况;需要连续三个元素中处于中间的元素要么比两边的元素小,要么比两边的元素大
  • 迭代策略
    当出现连续三个或者更多元素是递增/递减的情况时,选择最优(最后一个递增/递减的元素作为可以假如摇摆序列的转折点,因为最后一个元素最大/最小,相比与下一个元素,有更大的可能使得其也满足摇摆序列)
    比如[1,17,5,10,13,15,10,5,16,8] 中 [10,13,15] 三个连续递增,那么选择15则会使得下一个10也能够满足成为摇摆序列中的元素

实现算法(文末有完整测试代码):方法一

/*if..else if .. else */
int get_swing_seq(vector<int> &seq) {if(seq.size() <= 1) {return seq.size();}int max_len = 1;int i;for (i = 1; i < seq.size()-1; ++i) {if(seq[i-1] > seq[i] && seq[i] < seq[i+1]) { //满足递减转折时max_len ++;} else if(seq[i-1] < seq[i] && seq[i] > seq[i+1]) {//满足递增转折时max_len ++;}}/*handle the last element*/if(seq[i-2] > seq[i-1] && seq[i-1] < seq[i]) {max_len ++;} else if(seq[i-2] < seq[i-1] && seq[i-1] > seq[i]) {max_len ++;}return max_len;
}

实现算法:方法二
状态机的方式:

/*state machine: BEGIN,UP,DOWN*/
int get_swing_seq2(vector<int> &seq) {if(seq.size() <= 1) {return seq.size();}static const int BEGIN = 0;static const int UP = 1;static const int DOWN = 2;int STATE = BEGIN;int max_len = 1;for (int i = 1;i < seq.size(); ++i) {switch (STATE){case BEGIN:if(seq[i-1] > seq[i]) {STATE = DOWN;max_len ++;} else if (seq[i-1] < seq[i]) {STATE = UP;max_len ++;}break;case UP:if(seq[i-1] > seq[i]) {STATE = DOWN;max_len ++;}break;case DOWN:if(seq[i-1] < seq[i]) {STATE = UP;max_len ++;}break;default:break;}}return max_len;
}

实现算法:打印摇摆序列

/*if..else if .. else; return the result seq */
vector<int>  get_swing_seq3(vector<int> &seq) {if(seq.size() <= 1) {return seq;}vector<int> seq_result;int i;seq_result.push_back(seq[0]);for (i = 1; i < seq.size()-1; ++i) {if(seq[i-1] > seq[i] && seq[i] < seq[i+1]) {seq_result.push_back(seq[i]);} else if(seq[i-1] < seq[i] && seq[i] > seq[i+1]) {seq_result.push_back(seq[i]);}}/*handle the last element*/if(seq[i-2] > seq[i-1] && seq[i-1] < seq[i]) {seq_result.push_back(seq[i]);} else if(seq[i-2] < seq[i-1] && seq[i-1] > seq[i]) {seq_result.push_back(seq[i]);}return seq_result;
}

测试代码:

#include <iostream>
#include <algorithm>
#include <vector>using namespace std;/*if..else if .. else */
int get_swing_seq(vector<int> &seq) {if(seq.size() <= 1) {return seq.size();}int max_len = 1;int i;for (i = 1; i < seq.size()-1; ++i) {if(seq[i-1] > seq[i] && seq[i] < seq[i+1]) {max_len ++;} else if(seq[i-1] < seq[i] && seq[i] > seq[i+1]) {max_len ++;}}/*handle the last element*/if(seq[i-2] > seq[i-1] && seq[i-1] < seq[i]) {max_len ++;} else if(seq[i-2] < seq[i-1] && seq[i-1] > seq[i]) {max_len ++;}return max_len;
}/*if..else if .. else; return the result seq */
vector<int>  get_swing_seq3(vector<int> &seq) {if(seq.size() <= 1) {return seq;}vector<int> seq_result;int i;seq_result.push_back(seq[0]);for (i = 1; i < seq.size()-1; ++i) {if(seq[i-1] > seq[i] && seq[i] < seq[i+1]) {seq_result.push_back(seq[i]);} else if(seq[i-1] < seq[i] && seq[i] > seq[i+1]) {seq_result.push_back(seq[i]);}}/*handle the last element*/if(seq[i-2] > seq[i-1] && seq[i-1] < seq[i]) {seq_result.push_back(seq[i]);} else if(seq[i-2] < seq[i-1] && seq[i-1] > seq[i]) {seq_result.push_back(seq[i]);}return seq_result;
}/*state machine: BEGIN,UP,DOWN*/
int get_swing_seq2(vector<int> &seq) {if(seq.size() <= 1) {return seq.size();}static const int BEGIN = 0;static const int UP = 1;static const int DOWN = 2;int STATE = BEGIN;int max_len = 1;for (int i = 1;i < seq.size(); ++i) {switch (STATE){case BEGIN:if(seq[i-1] > seq[i]) {STATE = DOWN;max_len ++;} else if (seq[i-1] < seq[i]) {STATE = UP;max_len ++;}break;case UP:if(seq[i-1] > seq[i]) {STATE = DOWN;max_len ++;}break;case DOWN:if(seq[i-1] < seq[i]) {STATE = UP;max_len ++;}break;default:break;}}return max_len;
}int main(){vector<int> seq;int tmp;cout << "input seq " << endl;for (int i = 0;i < 10; ++i) {cin >> tmp;seq.push_back(tmp);}cout << "max of the swing seq len is " << get_swing_seq2(seq) << endl;vector<int> result = get_swing_seq3(seq);cout << "max of the swing seq is ";for (int i = 0;i < result.size(); ++i){cout << result[i] << " ";}return 0;
}

输出如下:

input seq
1 17 5 10 13 15 10 5 16 8
max of the swing seq len is 7
max of the swing seq is 1 17 5 15 5 16 8

贪心:Wiggle Subsequence 摇摆序列相关推荐

  1. 利用python实现贪心算法-----摇摆序列

    今天看到了这个贪心算法的摇摆序列,确实挺难的,自己就没有按照老师所用到的c语言代码编写,并且用了自己所能够理解的方式进行编写代码,代码实现起来有点多余,但是最终还是实现了,大家可以自己进行优化,这个是 ...

  2. 376 Wiggle Subsequence 贪心解法以及证明

    376. Wiggle Subsequence 题目理解 给定一个数组,相邻两个数计算差值.差值排成的序列是正负相间的,那这个数组就是一个wiggle 数组.例如数组[1,7,4,9,2,5],差值序 ...

  3. c++ 摇摆序列 (贪心+状态自动机)

    一个整数序列,如果相邻两个元素差是正负交替,则该序列为摇摆序列, 小于2个元素并且不相等,序列直接是摇摆序列 如 序列[1,7,4,9,2,5] 相邻元素差(6,-3,5,-7,3),是摇摆序列 序列 ...

  4. C++ 贪心算法 摇摆序列

    一个整数序列,如果两个相邻元素的差恰好正负(负正)交替出现,则该序列被称为摇摆序列.一个小于2个元素的序列直接为摇摆序列. #include<vector> class Solution ...

  5. 贪心法——LeetCode376 摆动序列

    贪心法 题目:摆动序列 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2 ...

  6. LeetCode376 摇摆序列

    如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个摆动序列, ...

  7. 贪心算法求解一个序列中出现次数最多的元素问题

    贪心算法求解一个序列中出现次数最多的元素问题 题目: 指定n个正整数,编写一个实验程序找出它们中出现次数最多的数.如果这样的数有多个,请输出其中最小的一个. 输入描述:输入的第1行只有一个正整数n(1 ...

  8. [Leetcode 376]摇摆序列 Wiggle Subsequence

    [题目] A sequence of numbers is called a wiggle sequence if the differences between successive numbers ...

  9. Leetcode376摇摆序列--贪心+自动机

    题目 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个摆动 ...

最新文章

  1. python基础知识ppt-python入门ppt下载
  2. LeetCode 143. 重排链表(Reorder List)
  3. [links]一写国内外著名人物的blog链接
  4. c语言adc采集取平均值,读取ADC值的浮动平均值
  5. 关于Mysql5.7高版本group by新特性报错
  6. 企业生产经营相关英文及缩写之(11)--Genenic 普通书写
  7. checking size of char… configure: error: cannot compute sizeof (char) 解决方法
  8. Prefix HDU - 5790 字典树 + 主席树
  9. 部署项目到jetty
  10. oracle19c的版本号_升级到 oracle 19c 的版本差异
  11. C++ WINDOWS下 wchar_t *和char * 相互转化总结篇
  12. linux Vue+nginx+django 实现前后端分离
  13. OpenJDK与JDK的区别分析
  14. 新冠病例继续攀升 苹果关闭纽约市所有实体店
  15. java登录界面圆形头像_自定义圆形头像
  16. 罗技无线网卡linux,linux(debian)安装USB无线网卡(tp-link TL-WN725N rtl8188eu )
  17. Silverlight 4 tools
  18. H3C WAP712C 路由器设置
  19. AutoCAD Plant 3d管道设计基础到中高级进阶视频教程
  20. 手机游戏后台服务整体架构

热门文章

  1. Android手机指令操作释疑
  2. fastJson的使用
  3. 企业支付宝账号开发接口实现
  4. 如何获取元素最终使用的css值
  5. 构建安全的 ASP.NET 网页和控件
  6. 用php做一个简单的汇率,vue实现简单实时汇率计算功能
  7. 硬盘显示容量和实际容量不符合_为啥我买的64G U盘实际只有57G?聊聊存储市场的“不足量”现象...
  8. android 美颜 技术点,《Android 美颜类相机开发汇总》第六章 Android OpenGLES 美妆定制实现...
  9. C语言 之 PTA乙级错误集锦
  10. php png jpg,php如何将png转换成jpg-PHP问题