「动态规划」如何求最长湍流子数组的长度?

2024-06-22 18:52

本文主要是介绍「动态规划」如何求最长湍流子数组的长度?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

78. 最长湍流子数组icon-default.png?t=N7T8https://leetcode.cn/problems/longest-turbulent-subarray/description/

给定一个整数数组arr,返回arr的最长湍流子数组的长度。如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是湍流子数组。更正式地来说,当arr的子数组A[i], A[i+1], ..., A[j]满足下列条件时,我们称其为湍流子数组:若 i <= k < j:当k为奇数时,A[k] > A[k+1],且当k为偶数时,A[k] < A[k+1];或若i <= k < j:当k为偶数时,A[k] > A[k+1],且当k为奇数时,A[k] < A[k+1]。

  1. 输入:arr = [9,4,2,10,7,8,8,1,9],输出:5,解释:arr[1] > arr[2] < arr[3] > arr[4] < arr[5]。
  2. 输入:arr = [4,8,12,16],输出:2。
  3. 输入:arr = [100],输出:1。

提示:1 <= arr.length <= 4 * 10^4,0 <= arr[i] <= 10^9。


我们用动态规划的思想来解决这个问题。

确定状态表示:根据经验和题目要求,我们用dp[i]表示:以i位置为结尾的所有子数组中,最长湍流子数组的长度。但是这样的状态表示推不出状态转移方程,所以我们需要更细的划分:

  • 用f[i]表示:以i位置为结尾的所有最后呈现上升趋势的子数组中,最长湍流子数组的长度
  • 用g[i]表示:以i位置为结尾的所有最后呈现下降趋势的子数组中,最长湍流子数组的长度

推导状态转移方程:考虑最近的一步。以i位置为结尾的湍流子数组和以i - 1位置为结尾的湍流子数组有什么关系呢?以f[i]为例,分类讨论:

  • 如果arr[i - 1] >= arr[i],那么以i位置为结尾的最后呈现上升趋势的最长湍流子数组就是arr[i]本身,即f[i] = 1。
  • 如果arr[i - 1] < arr[i],那么以i位置为结尾的最后呈现上升趋势的最长湍流子数组,就应该是「以i - 1位置为结尾的最后呈现下降趋势的最长湍流子数组」的末尾添加arr[i]之后,形成的湍流子数组,即f[i] = g[i - 1] + 1。

综上所述:f[i] = arr[i - 1] >= arr[i] ? 1 : g[i - 1] + 1。同理,g[i] = arr[i - 1] <= arr[i] ? 1 : f[i - 1] + 1。换句话说,f[i]和g[i]默认是1,如果arr[i - 1] < arr[i],那么f[i] = g[i - 1] + 1;如果arr[i - 1] > arr[i],那么g[i] = f[i - 1] + 1

初始化:根据状态转移方程,我们需要初始化f[0]和g[0]的值,防止越界。显然f[0] = g[0] = 1

填表顺序:根据状态转移方程,显然应从左往右,同时填两个表

返回值:根据状态表示,由于我们不确定最长湍流子数组的结束位置,所以应返回f表和g表中,所有元素的最大值

细节问题:显然f表和g表的规模和arr相同,均为1 x n

时间复杂度:O(N),空间复杂度:O(N)。

class Solution {
public:int maxTurbulenceSize(vector<int>& arr) {int n = arr.size();// 创建dp表vector<int> f(n, 1);auto g = f;// 填表for (int i = 1; i < n; i++) {if (arr[i - 1] < arr[i]) {f[i] = g[i - 1] + 1;} else if (arr[i - 1] > arr[i]) {g[i] = f[i - 1] + 1;}}// 返回结果return max(*max_element(f.begin(), f.end()),*max_element(g.begin(), g.end()));}
};

这篇关于「动态规划」如何求最长湍流子数组的长度?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1085125

相关文章

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可