首页 > 贪心:Wiggle Subsequence 摇摆序列

贪心:Wiggle Subsequence 摇摆序列

一个整数序列,如果两个相邻元素的差恰好正负(负正)交替出现,则该序列被称为

摇摆序列。一个小于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 
#include 
#include 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 

更多相关:

  • 前言 seq命令用于产生从某个数到另外一个数之间的所有整数。 命令格式 seq [OPTION]... LAST seq [OPTION]... FIRST LAST seq [OPTION]... FIRST INCREMENT LAST 支持将指定范围的数字打印出来,按照指定的递增规律 -f, --format=格式...

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • #include #include #include #include #include #include #include

  • 题目:表示数值的字符串 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"及"-1E-16"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。 解题: 数值错误的形式有多种多样,但是正确的...

  • 加法伺候  //超过20位数值相加---------------------------------------- function bigNumAdd(a, b) {if (!(typeof a === "string" && typeof b === "string")) return console.log("传入参数必...

  • 业务场景: 从中文字句中匹配出指定的中文子字符串 .这样的情况我在工作中遇到非常多, 特梳理总结如下. 难点: 处理GBK和utf8之类的字符编码, 同时正则匹配Pattern中包含汉字,要汉字正常发挥作用,必须非常谨慎.推荐最好统一为utf8编码,如果不是这种最优情况,也有酌情处理. 往往一个具有普适性的正则表达式会简化程...

  • 简单record 一下 #include // 'struct sockaddr_in' #include #include // 'struct ifreq' and 'struct if_nameindex' #include #inc...