【经典专题】颠簸的波浪——摆动数组问题的标准答案
引入定义
如果连续数字之间的差严格地在正数和负数之间交替,称为摆动数组。
举几个例子。[1,7,4,9,2,5]
是一个典型的摆动数组,它就像颠簸的波浪;[1,7,4,5,5]
不是摆动数组,因为它不是严格的上下摆动;[1]
和[1,5]
都符合定义,是摆动数组。
题目两则
Q1. 返回数组所包含的最大连续摆动数组的长度。
输入:[9,4,2,10,7,8,8,1,9]
输出:5
解释:[4,2,10,7,8]长度为2
Q2. 返回数组所包含的最大摆动数组的长度,不要求连续。
输入:[1,17,5,10,13,15,10,5,16,8]
输出:7
解释:[1,17,10,13,10,16,8]长度为7
答案两则
- 摆动数组的答案比较模板化———用两个变量记录此时摆动数组的长度情况(up, down)
- up的意义是,遍历到该处时,假设摆动数组正处于上升状态,它的长度;down的意义是,遍历到该处时,假设摆动数组正处于下降状态,它的长度
- 必须要理解的是,这两个摆动数组并不是同一个,因为我们假设了其结尾分别处于上升/下降状态
- 关键还在于这两个状态的转换,即up和down交叉转换(联系股票问题)
- 因为Q1要求连续,因此当摆动数组断裂时,up/down要重置为1;而Q2不要求连续,即摆动数组隐藏在整个数组中,up/down不需要重置,只需要继承(关键区别)
class Solution {public int maxTurbulenceSize(int[] arr) {int up = 1;int down = 1;int res = 1;for(int i = 1; i < arr.length; i++) {if(arr[i] > arr[i - 1]) {up = down + 1;down = 1;} else if(arr[i] < arr[i - 1]) {down = up + 1;up = 1;} else {up = 1;down = 1;}res = Math.max(res, Math.max(up, down));}return res;}
}
class Solution {public int maxTurbulenceSize(int[] arr) {int up = 1;int down = 1;for(int i = 1; i < arr.length; i++) {if(arr[i] > arr[i - 1]) {up = down + 1;}if(arr[i] < arr[i - 1]) {down = up + 1;}}return Math.max(up, down);}
}
思考探究
等一下,这种状态的交叉转化,让我们想到了经典的股票问题(戳这里),因此所谓的up/down模板,会不会就是动态规划经过滚动数组优化的结果?
是的。
下面我们从动态规划的角度,来还原出这道题完整的思路演化过程。
dp[i][0]
的含义是,以i处为结尾的且结尾处于上升状态的摆动数组的最大长度
dp[i][1]
的含义是,以i处为结尾的且结尾处于下降状态的摆动数组的最大长度
// 状态转移
if(arr[i] > arr[i - 1]) {dp[i][0] = dp[i][1] + 1;
}
if(arr[i] < arr[i - 1]) {dp[i][1] = dp[i][0] + 1;
}// 滚动优化
if(arr[i] > arr[i - 1]) {dp[0] = dp[1] + 1;
}
if(arr[i] < arr[i - 1]) {dp[1] = dp[0] + 1;
}
一点理解
动态规划中,定义出dp[i][0/1]的含义是关键点也是难点。记住一件事,dp[i]的含义是“此时/此地完成了i的变化后,所处状态(0/1)所对应的值”,关键在于“状态”;
在股票问题中,dp[i][0/1]的含义倾向于状态(持股/不持股)而非动作(买入/卖出);在摆动数组中,dp[i][0/1]的含义也是倾向于状态(上升下降的状态)而非动作(上升下降的动作)———理解状态二字,至关重要。
ENDENDEND
【经典专题】颠簸的波浪——摆动数组问题的标准答案相关推荐
- C++入门经典-例6.23-字符串数组赋值与string
C++入门经典-例6.23-字符串数组赋值与string 1:代码如下: // 6.23.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #i ...
- php判断二维数组里值均为空,php中经典方法实现判断多维数组是否为空
php中经典方法实现判断多维数组是否为空 复制代码 代码如下: //判断一个数组是否为空 /** array( ); 空 array( array( ), array( ), array( ) ); ...
- CSP:CSP认证考试:202109-1(数组推导)满分答案,Java版
CSP:CSP认证考试:202109-1(数组推导)满分答案,Java版 一.题目: 二.Java满分答案 import java.util.ArrayList; import java.util.S ...
- 牛客题霸 [ 未排序数组中累加和为给定值的最长子数组长度] C++题解/答案
牛客题霸 [ 未排序数组中累加和为给定值的最长子数组长度] C++题解/答案 题目描述 给定一个无序数组arr, 其中元素可正.可负.可0.给定一个整数k,求arr所有子数组中累加和为k的最长子数组长 ...
- LeetCode (二分小专题)33搜索旋转排序数组34在排序数组中查找元素的第一个和最后一个位置35搜索插入位置
前言 国庆前最后一次打卡,国庆后继续开启,公众号bigsai回复进群欢迎加入打卡,如有帮助记得点赞收藏. 近期打卡记录: LeetCode 32最长有效括号(困难) (本周) LeetCode 30串 ...
- 经典面试题:将有序数组、有序链表转换成平衡二叉树
微信搜一搜:bigsai 大家都在关注的刷题.学习数据结构和算法宝藏项目 关注回复进群即可加入力扣打卡群,欢迎划水. 将有序数组转换成平衡二叉树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜 ...
- 【经典题目——排序】1、数组元素编号
[题目] 从键盘输入10个整数存放在数组a中,然后对数组a中的10个整数按从小到大连续编号,要求不能改变数组a中元素的顺序,且相同的整数要具有相同的编号.最后输出数组a及其元素的编号. [源代码] # ...
- 【经典专题】反转链表——如何在链表中穿针引线
反转整个链表(简单) 很简单且经典的题目.就是将 1->2->3->4->5 反转为 5->4->3->2->1. 有两种思路,迭代和递归.先看图再看代 ...
- 【机器学习】经典的机器学习200道面试题(附参考答案)
来 源: https://blog.csdn.net/sinat_35512245/article/details/78796328 本文总结了往年BAT机器学习面试题,干货满满,值得收藏. 想要入 ...
最新文章
- 计算机中丢失boost,boost_system.dll
- **52.常用的存储保护方法有哪些?
- 动态规划之最长公共子序列(LCS)
- 京东笔试4.2-19:00随笔
- Bootstrap中的网格系统
- 通过命令行获取计算机参数,Win32命令行参数的传到和获取
- ElasticSearch的中文分词
- 冒泡排序法_排序算法 冒泡排序法
- @IT老司机 云服务、BI大数据、协同办公等五大技术选型研讨会,震撼来袭!
- PAT 1071. 小赌怡情(15)-PAT乙级真题
- nginx反向代理解决跨域
- 读书笔记之:C++程序设计陷阱
- python必背100源代码-python 100例 (持续更新)
- Python 并发简介(多线程、多进程)
- DlhSoft Kanban,WPF 的看板组件
- 3dsmax展UV,制作UV贴图,将物体的贴图放到一张图片上,贴图优化方式,UVW贴图制作全流程
- 当代超吸金的行业“Python工程师”,如何快速从Pytho入门到初级Python工程师?
- LPVOID 和CString 的转换
- 2. Bean Validation声明式校验方法的参数、返回值
- Quartus II -Warning (15714):Some pins have incomplete I/O assignments. Refer to the I/O Assignment
热门文章
- 监控工具Kafka-eagle介绍
- android仿支付宝收款播报,【iOS】实现类似支付宝收钱语音播报功能
- 将多个PDF合成一个的方法
- 2020省赛->棋盘放麦子
- 省政协委员、南京大学人工智能学院院长周志华: 科研学习探索最重要的是“兴趣”和“勤奋”...
- 增长渠道价值衡量,LTV与CAC
- with(), within() 和 transform()的简单比较
- DATALOAD必须要注意的选项
- 微软最新提供的project2010帮助资料
- 在centos上安装httpd,并实现html文件和cgi文件在网页上显示,搭建静态web网页