LeetCode 例题精讲 | 17 动态规划如何拆分子问题,简化思路

8892246bcd89f896623862abe23a57b0.jpeg

在上一篇文章中,我们讲解了「子数组」类动态规划题目的常见技巧。这篇文章继续讲解动态规划问题中的小技巧。今天要讲的是「如何定义多个子问题」。

常规的动态规划问题只需要定义一个子问题即可。然而在某些情况下,把子问题拆成多个会让思路更清晰。如果你没用过这个技巧的话,不妨跟着今天的例题来学习学习。

本篇文章的内容包括:

  • 如何拆分动态规划的子问题

  • 「最长波形子数组」问题的解法

  • 度假问题的解法

  • 多个子问题与二维子问题的转换关系

最长波形子数组

我们用「最长波形子数组」的解题过程来展示定义多个子问题在解题中的作用。

LeetCode 978. Longest Turbulent Subarray 最长波形子数组(Medium)

A 的子数组 A[i..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]

也就是说,如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是波形子数组。

返回 A 的最长波形子数组的长度。

首先我们要明白「波形子数组」的含义。(吐槽一句,官方把 trubulent 翻译成「湍流」,这翻译是给人看的吗?)我们关注的是数组中相邻元素之间的大小关系。如果后一个元素大于前一个元素,则是数组的「上升段」;反之,则是数组的「下降段」。那么,「波形子数组」就是一段交替上升下降的子数组。例如输入 [9, 4, 2, 10, 7, 8, 8, 1, 9] 中, [4, 2, 10, 7, 8] 是其中最长的一段波形子数组。

de1e3ab1567759c3c7bc40380600722c.jpeg
「波形子数组」是一段交替上升下降的子数组

使用单个子问题求解

我们先看看使用传统的单个子问题该怎么求解这道题。

首先,看到题目中的「子数组」字样,我们应当立即想到子数组相关的解题技巧:在定义子问题的时候给子问题加上位于数组尾部的限制。

不理解这个解题技巧的同学,可以回顾我的上一篇文章:

LeetCode 例题精讲 | 16 最大子数组和:子数组类问题的动态规划技巧

使用这个技巧,我们可以这样定义子问题:

子问题 表示「数组 A[0..k) 中,位于数组尾部的最长波形子数组」。

之所以要限制子问题中求的最长波形子数组位于数组尾部,是因为只有数组尾部的波形子数组才可以和新加入

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值